You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于AWS MFA的GitLab CI流水线认证权限问题求助

解决GitLab CI流水线推送ECR的身份认证问题

问题根源

你遇到的AccessDenied错误,核心原因有两个:

  1. 自托管在EC2上的GitLab Runner默认会继承EC2实例的IAM角色权限,但这个角色没有被允许调用sts:AssumeRoleWithWebIdentity操作;
  2. 你创建的GitLab_Role是Web Identity类型角色,只能通过GitLab的OIDC令牌申请临时凭证,无法直接绑定给EC2实例使用。

分步解决方案

1. 给EC2实例角色添加权限

找到GitLab Runner所在EC2实例使用的IAM角色(比如命名为EC2_GitLab_Runner_Role),添加以下权限策略,允许它调用STS服务获取GitLab_Role的临时凭证:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Resource": "arn:aws:iam::你AWS账号ID:role/GitLab_Role"
        }
    ]
}

2. 修正.gitlab-ci.yml的凭证获取逻辑

不要让Runner直接用Web Identity去AssumeRole,而是先借助EC2实例角色的权限,拿GitLab的OIDC令牌申请GitLab_Role的临时凭证,再用这些凭证操作ECR。示例配置如下:

stages:
  - build-and-push

build-ecr-image:
  stage: build-and-push
  image: docker:latest
  services:
    - docker:dind
  before_script:
    # 安装AWS CLI和jq(用于解析JSON输出)
    - apk add --no-cache aws-cli jq
    # 定义关键变量
    - export AWS_ROLE_ARN="arn:aws:iam::你AWS账号ID:role/GitLab_Role"
    - export AWS_WEB_IDENTITY_TOKEN_FILE="/tmp/gitlab-jwt-token"
    # 将GitLab提供的JWT令牌写入文件
    - echo "${CI_JOB_JWT_V2}" > $AWS_WEB_IDENTITY_TOKEN_FILE
    # 调用STS服务获取GitLab_Role的临时凭证
    - |
      CREDS=$(aws sts assume-role-with-web-identity \
        --role-arn $AWS_ROLE_ARN \
        --role-session-name "gitlab-ci-${CI_JOB_ID}" \
        --web-identity-token file://$AWS_WEB_IDENTITY_TOKEN_FILE)
    # 导出临时凭证到环境变量
    - export AWS_ACCESS_KEY_ID=$(echo $CREDS | jq -r '.Credentials.AccessKeyId')
    - export AWS_SECRET_ACCESS_KEY=$(echo $CREDS | jq -r '.Credentials.SecretAccessKey')
    - export AWS_SESSION_TOKEN=$(echo $CREDS | jq -r '.Credentials.SessionToken')
    # 登录ECR仓库
    - aws ecr get-login-password --region 你的AWS区域 | docker login --username AWS --password-stdin 你AWS账号ID.dkr.ecr.你的AWS区域.amazonaws.com
  script:
    # 构建镜像
    - docker build -t 你的ECR仓库URI:${CI_COMMIT_SHORT_SHA} .
    # 推送镜像到ECR
    - docker push 你的ECR仓库URI:${CI_COMMIT_SHORT_SHA}

3. 校验GitLab_Role的信任关系

确保GitLab_Role的信任关系配置正确,仅允许你指定的GitLab项目通过OIDC访问:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::你AWS账号ID:oidc-provider/gitlab.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "gitlab.com:aud": "https://gitlab.com",
                    "gitlab.com:sub": "project_path:你的GitLab用户名/你的项目名:*"
                }
            }
        }
    ]
}

4. 确认Runner环境配置

  • 自托管Runner无需额外配置AWS密钥,只要所在EC2实例拥有上述添加的权限即可;
  • 确保GitLab项目中CI_JOB_JWT_V2变量已启用(前往项目设置→CI/CD→变量,展开预定义变量确认);
  • 将所有占位符(如账号ID、区域、仓库URI)替换为你自己的实际信息。

关键提醒

  • 遵循最小权限原则:EC2实例角色仅需拥有AssumeGitLab_Role的权限,无需直接配置ECR相关权限;
  • 临时凭证自带有效期,每次流水线会自动重新获取,无需手动管理过期问题;
  • 若仍报错,可查看AWS CloudTrail日志,确认调用STS的角色身份及具体拒绝原因。

内容的提问来源于stack exchange,提问作者Marrsail Bailey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 15:45:03