Hashicorp Vault策略授权失败:GitLab CI JWT认证无法读取密钥
问题描述
尝试通过JWT认证结合GitLab CI与Hashicorp Vault为CI作业提供密钥,所有操作步骤均已完成,但遇到权限问题:
- CI流水线读取
gitlab/k8s-gcp-env/gcp密钥时返回403权限拒绝 - 本地生成带有
k8s-gcp-env策略的token,执行vault token capabilities gitlab/k8s-gcp-env/gcp显示拥有read、list权限,但实际读取该路径仍报403 - 仅Root Token可正常读取该密钥路径
操作步骤如下:
- 启用JWT认证方法:
vault auth enable jwt
- 创建策略:
vault policy write k8s-gcp-env - <<EOF path "gitlab/k8s-gcp-env/*" { capabilities = [ "read", "list" ] } EOF
- 创建JWT角色:
vault write auth/jwt/role/k8s-gcp-env - <<EOF { "role_type": "jwt", "policies": ["k8s-gcp-env"], "token_explicit_max_ttl": 60, "bound_claims_type": "glob", "bound_claims": { "project_id": "28" } } EOF
- 配置JWT认证方法(自定义CA):
vault write auth/jwt/config \ jwks_url="https://git.__REDACTED__/-/jwks" \ bound_issuer="git.__REDACTED__" \ jwks_ca_pem=@/Users/user/Downloads/c81a8bd1f9cf6d84c525f378ca1d3f8c30770e34.cer
问题排查与解决思路
1. 检查KV存储引擎版本(最可能的原因)
如果你的gitlab路径使用的是KV v2存储引擎,Vault会自动在存储路径前添加/data/前缀。例如你存储的密钥路径是gitlab/k8s-gcp-env/gcp,实际API访问路径为gitlab/data/k8s-gcp-env/gcp。
当前策略路径gitlab/k8s-gcp-env/*无法匹配KV v2的实际路径,导致权限拒绝。修改策略为:
vault policy write k8s-gcp-env - <<EOF path "gitlab/data/k8s-gcp-env/*" { capabilities = [ "read", "list" ] } EOF
2. 验证策略路径匹配精度
- 确认密钥完整存储路径:执行
vault kv get gitlab/k8s-gcp-env/gcp,查看输出中的path字段确认实际路径 - 若密钥直接存储在
gitlab/k8s-gcp-env路径下(而非子路径),需补充path "gitlab/k8s-gcp-env"的权限配置
3. 确认角色与策略的关联
执行vault read auth/jwt/role/k8s-gcp-env,检查输出中的policies字段是否包含k8s-gcp-env,确保策略已正确绑定到角色。
4. 检查命名空间配置(若启用)
如果Vault启用了命名空间,需确认:
- 策略创建在密钥所在的命名空间下
- JWT认证方法配置在对应命名空间中
- CI作业的认证请求指向正确的命名空间
GitLab CI与Hashicorp Vault认证集成参考(官方文档翻译)
官方文档核心要点:
- GitLab CI会为每个作业生成唯一的JWT令牌,Vault通过验证令牌的签名和声明(如
project_id、job_id等)授予权限 - 针对KV v2存储引擎,策略路径必须包含
/data/前缀,例如要访问secret/my-project/api-key,策略路径应为path "secret/data/my-project/*" - 角色的
bound_claims需匹配GitLab JWT令牌中的声明,确保只有指定项目或作业的CI流水线能获取Vault令牌
内容的提问来源于stack exchange,提问作者Soggetto insubordinato
相关产品推荐
相关产品推荐

