GitLab CI无法访问Vault:JWT用户声明缺失问题排查
GitLab CI Vault JWT认证:user_claim配置错误解决方法
问题背景
环境:GitLab Community Edition 14.2.7
已执行的操作:
- 获取GitLab JWKS:
curl -s -k -X GET https://gitlab.domain.com/-/jwks {"keys":[{"kty":"RSA","kid":"xUeI9jobL................194Xg0gj5DSct8O__KR6I8RoTTBACp1lRYSlBO4w","use":"sig","alg":"RS256"}]}
- Vault端配置:
- 创建密钥:
vault kv put secret/projects/test/mariadb login=user password=pass
- 创建策略:
vault policy write project-test - <<EOF path "secret/projects/test/*" { capabilities = [ "read" ] } EOF
- 创建JWT角色(错误配置点):
vault write auth/jwt/role/project-test - <<EOF { "role_type": "jwt", "policies": ["project-test"], "token_explicit_max_ttl": 60, "user_claim": "my@mail.com", "bound_claims": { "project_id": "321", "ref": "main", "ref_type": "branch" } } EOF
- 配置JWT认证:
vault write auth/jwt/config jwks_url="https://gitlab.domain.com/-/jwks" bound_issuer="gitlab.domain.com"
确认project_id和分支main均正确。
- GitLab CI脚本配置:
stages: - test_vault test: stage: test_vault script: - echo $CI_COMMIT_REF_NAME - export VAULT_ADDR=https://k8s.domain.com:8700 - export VAULT_TOKEN="$(vault write -field=token auth/jwt/login role=project-test jwt=$CI_JOB_JWT)" - export LOGIN="$(vault kv get -field=login secret/projects/test/mariadb)" - export PASSWORD="$(vault kv get -field=password secret/projects/test/mariadb)" - echo $LOGIN - echo $PASSWORD
执行时出现错误:
$ export VAULT_ADDR=https://k8s.domain.com:8700 $ export VAULT_TOKEN="$(vault write -field=token auth/jwt/login role=project-test jwt=$CI_JOB_JWT)" Error writing data to auth/jwt/login: Error making API request. URL: PUT https://k8s.domain.com:8700/v1/auth/jwt/login Code: 400. Errors: * claim "my@mail.com" not found in token
提问:正确的user_claim应该如何设置?
解决方法
错误核心是user_claim被设置成了具体的邮箱字符串my@mail.com,但该字段需要指定GitLab JWT令牌中实际存在的声明字段名,而非字段值。
正确配置方式
GitLab CI生成的JWT令牌包含标准声明字段,用于标识用户的常用字段是email,因此需将user_claim设置为email:
重新创建JWT角色:
vault write auth/jwt/role/project-test - <<EOF { "role_type": "jwt", "policies": ["project-test"], "token_explicit_max_ttl": 60, "user_claim": "email", "bound_claims": { "project_id": "321", "ref": "main", "ref_type": "branch" } } EOF
验证令牌声明字段(可选)
若不确定令牌内的字段,可在GitLab CI脚本中临时解码查看所有可用声明:
script: - echo $CI_JOB_JWT | base64 -d | jq .
执行后会列出令牌包含的所有字段(如email、sub、username等),可根据需求选择合适字段作为user_claim。
内容的提问来源于stack exchange,提问作者Maksim
相关产品推荐
相关产品推荐

