gitlab deploy Token 必须在 auth.json 中以 gitlab-token 类型显式配置,域名需含协议,token 填入 token 字段;私有包还需在 repositories 中用 package 类型声明完整 https 克隆地址及准确 name。

GitLab Deploy Token 配置后仍提示 401 Unauthorized
Deploy Token 必须在 auth.json 中显式声明为 gitlab-token 类型,否则 composer 默认按 Personal access Token 解析,导致认证失败。常见错误是直接把 Deploy Token 的 token 值填进 http-basic 字段,这完全无效。
- 在项目根目录的
auth.json中,用gitlab-token键而非http-basic -
gitlab-token的值必须是完整的 GitLab 实例域名(含协议和端口),不能省略https://或写成gitlab.example.com - Token 值填在
token字段下,不是password—— Deploy Token 没有用户名概念,username字段可任意设(如"deploy"),但不能省略
{ "gitlab-token": { "https://gitlab.example.com": { "username": "deploy", "token": "glpat-xxxxxxxxxxxxxxxxxxxx" } } }
composer install 报错 “Could not parse version constraint” 或跳过私有包
Deploy Token 本身不解决包发现逻辑问题;Composer 仍需知道去哪里找包。如果 composer.json 中没配置正确的仓库类型和 URL,即使认证通过,也会因无法解析 composer.json 元数据而失败。
- 私有 GitLab 包必须使用
package类型仓库,不能只靠vcs自动发现 —— Deploy Token 不支持vcs模式下的元数据拉取 -
url必须指向 GitLab 项目的 HTTPS 克隆地址(如https://gitlab.example.com/group/pkg.git),不是 Web 页面 URL - 确保该包的
composer.json中name字段与require中声明的完全一致(包括 vendor 名)
{ "repositories": [ { "type": "package", "package": { "name": "myorg/my-pkg", "version": "dev-main", "source": { "url": "https://gitlab.example.com/myorg/my-pkg.git", "type": "git", "reference": "main" } } } ] }
为什么不用 Personal Access Token?Deploy Token 的权限边界在哪
Personal Access Token 默认拥有用户全部权限(包括读写代码、修改 CI/CD、删除项目),一旦泄露或误配,风险远超必要。Deploy Token 是唯一能精确限定为「只读包代码 + 只读仓库元数据」的凭证。
- Deploy Token 权限仅限于
read_repository,且仅对指定项目生效 —— 即使被硬编码进 CI 脚本或容器镜像,攻击者也无法提权或横向移动 - Personal Access Token 在
auth.json中若未加gitlab-token封装,会被 Composer 当作全局 HTTP Basic 凭据发送,可能意外暴露给其他非 GitLab 域名 - Deploy Token 不绑定任何用户账户,禁用对应项目后自动失效,无需人工轮换
CI 环境中 auth.json 的安全注入方式
直接把 auth.json 提交进 Git 或写死在 Dockerfile 里等于公开密钥。GitLab CI 必须用 CI_JOB_TOKEN 或变量注入,且避免日志回显。
- 在
.gitlab-ci.yml中用before_script动态生成auth.json,内容从DEPLOY_TOKENCI 变量读取 - 务必设置
DEPLOY_TOKEN变量为 “masked” 和 “protected”,防止被子 pipeline 或日志捕获 - 不要用
composer config命令写入凭证 —— 它会把 token 写进COMPOSER_HOME,可能污染共享 runner 缓存
before_script: - mkdir -p $HOME/.composer - echo '{"gitlab-token":{"https://gitlab.example.com":{"username":"deploy","token":"'$DEPLOY_TOKEN'"}}}' > $HOME/.composer/auth.json
Deploy Token 的核心约束在于:它只管「我能拉哪段代码」,不管「我该拉哪个版本」。版本解析、依赖合并、autoload 生成这些事,全靠你手写的 package 配置是否准确 —— 这部分出错,错误信息往往和认证无关,容易绕晕。