必须使用gitlab-token字段,而非http-basic或token;域名key须与仓库URL host逐字符严格匹配;Token权限需同时启用read_api和read_repository。

auth.json 里必须用 gitlab-token 字段,不是 http-basic 或 token
Composer 对 GitLab 的 Personal Access Token 有专用字段名:gitlab-token。填成 http-basic、token、access_token 都不会生效——它根本不会读。错误配置下,composer install 日志里看不到 Authorization: Bearer glpat- 请求头,但报错却只显示模糊的 “Could not fetch”,让人误以为是网络或权限问题。
正确写法示例:
{"gitlab-token": {"gitlab.com": "glpat-xxxxxxxxxxxxxxxxxxxx"}}自建 GitLab 实例(如 gitlab.example.com)也一样,key 必须是纯域名,且字段名严格为 gitlab-token。
域名 key 必须和仓库 URL 的 host 完全一致,逐字符比对
这不是“差不多就行”的匹配。如果 repositories.url 是 https://gitlab.example.com:8443/group/pkg.git,那 auth.json 里的 key 就得是 "gitlab.example.com:8443"——端口少一个都不行;带 www 就必须带 www;大小写敏感;协议和路径一律不参与匹配。
-
{"https://gitlab.example.com": {}}→ 协议前缀导致失效 -
{"gitlab.example.com/api/v4": {}}→ 路径被当域名,不匹配 -
{"gitlab.example.com": {}}但 URL 含:8443→ 缺端口,认证跳过
验证方法:运行 composer config --global --list | grep gitlab,看是否输出对应域名的配置项。
Token 权限必须同时开启 read_api 和 read_repository
Composer 拉私有包分两步:先调 /api/v4/projects/ 查元数据(需要 read_api),再执行 git clone --mirror 下代码(需要 read_repository)。缺一不可。
在 OpenClaw 中管理 GitHub 仓库、Pull Request、Issue 与工作流。适用于审查 PR、管理 Issue、自动化 GitHub Actions、同步仓库等场景。
- 只开
read_api→ 报403 Forbidden on /api/v4/projects/ - 只开
read_repository→ 报Failed to download: Failed to execute git clone --mirror - 用 Deploy Token、CI_JOB_TOKEN、OAuth App Token → 第一步就卡死,因为它们不支持 GitLab API 调用
生成位置:GitLab 用户 Settings → Access Tokens → 勾选 read_api 和 read_repository,名称建议标注用途(如 composer-read-only)。
CI/CD 中别硬编码,用环境变量动态生成 auth.json
把 auth.json 提交进代码库等于泄露凭证。CI/CD 环境应禁用静态文件,改用加密环境变量 + 运行时生成。
例如 GitLab CI:
before_script:
- echo "{\"gitlab-token\": {\"gitlab.example.com\": \"$GITLAB_COMPOSER_TOKEN\"}}" > auth.json
- export COMPOSER_AUTH=$(cat auth.json | base64 -w0)关键点:
- 不用
COMPOSER_AUTH就必须确保auth.json在项目根目录,且 Composer 版本 ≥ 2.2(旧版只认全局路径) - Windows 下全局路径是
%APPDATA%\Composer\auth.json,Linux/macOS 是~/.composer/auth.json,权限必须设为600 - GitLab CI 可直接用
$CI_JOB_TOKEN,但仅限当前项目,跨项目需另配 PAT
最易被忽略的是:哪怕 Token 正确、域名匹配、权限齐全,只要 repositories 没声明为 "type": "vcs" 且 URL 不以 .git 结尾,Composer 就压根不触发认证流程——它连请求都不会发出去。

















