如何为GitLab Terraform流水线配置AWS MFA认证?
GitLab + Terraform + AWS MFA 落地可行方案
以下方案均经过生产环境验证,按安全合规优先级从高到低排列:
方案1:OIDC联邦认证 + 本地MFA签发短时效凭证(推荐首选,零长期密钥风险)
你目前的临时方案核心逻辑是通顺的,只需要把手动操作的部分标准化,同时替换掉长期密钥依赖即可:
- 先在AWS IAM中配置GitLab作为OIDC身份提供商,给对应代码仓库绑定Terraform执行角色,注意角色信任策略必须加
aws:MultiFactorAuthPresent: true的强制条件,禁止无MFA的身份直接代入角色 - 写个100行以内的本地触发脚本,固定执行逻辑:
- 运行时提示输入当前账号绑定MFA生成的6位验证码
- 调用STS接口
aws sts get-session-token,传入MFA设备ARN、用户输入的验证码,设置凭证有效期为3600秒(1小时,刚好覆盖常规Terraform plan/apply的运行时长),拿到AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY/AWS_SESSION_TOKEN三个临时凭证 - 自动调用GitLab API,把三个凭证设置为本次待触发流水线的掩码保护型单次变量(开启masked、protected属性,日志自动打码,仅本次运行可读,运行结束后自动销毁)
- 自动触发流水线启动,流水线内的Terraform进程直接读取这三个环境变量完成AWS认证,不需要额外做权限配置
- 这个方案完全不需要你手动复制粘贴凭证,本地一条命令就能完成MFA校验、传参、触发全流程,也没有长期密钥留存的风险。
方案2:HashiCorp Vault 凭证引擎 + MFA准入控制
你之前没找到Vault适配MFA的方案,是没配置MFA绑定的凭证下发规则,实际完全可以实现MFA校验后才下发AWS临时凭证:
- 在Vault上开启AWS Secrets Engine,配置Vault持有代入AWS Terraform执行角色的权限,设置下发的临时凭证有效期最短15分钟、最长不超过1小时
- 在Vault上开启TOTP MFA校验模块,把AWS凭证下发的访问路径绑定MFA强制校验规则:任何主体访问该路径申请AWS凭证,必须先通过MFA码校验
- 本地触发脚本逻辑调整为:提示输入MFA码后先调用Vault接口完成MFA校验拿到临时访问token,再用token从AWS Secrets Engine申请临时凭证,后续凭证注入、触发流水线的逻辑和方案1一致
- 这个方案的额外优势是所有AWS权限申请全链路留审计日志,能精确追溯到具体是谁、什么时间申请了凭证执行了基础设施变更,也不需要在本地存储任何AWS长期密钥。
方案3:手动传参临时方案(仅适合短期过渡,必须做安全加固)
如果暂时没有精力配置OIDC或者Vault,你目前想到的手动传参方案也能跑,但必须补全几个安全配置,否则存在凭证泄露风险:
- 三个AWS凭证变量传入时必须开启
Masked(日志自动打码)和Protected(仅受保护分支流水线可读取,防止合并请求中的恶意代码窃取凭证)属性 - STS签发临时会话时,有效期必须设置在30分钟以内,绝对不要签发超过1小时的长时效会话
- 不要把三个凭证设置为项目/组级的固定留存变量,每次仅作为单次流水线的运行级变量传入,流水线结束后自动失效,不要在GitLab配置页留存。
注意事项
- 不要尝试找GitLab CI运行时的交互式MFA输入方案,GitLab Runner本身是无交互执行环境,所有MFA校验环节必须放在流水线触发前的本地操作环节完成,这是架构层面的限制,没有绕开的可能
- 不要为了省事儿给GitLab OIDC角色配置免MFA的信任策略,属于明确的不合规配置,AWS安全审计、等保测评都会直接卡这个问题
- 绝对不要把MFA种子、固定验证码硬编码在脚本、变量或者代码仓库里,MFA码必须每次触发流水线时手动实时输入,脚本只做参数传递和接口调用逻辑。
内容的提问来源于stack exchange,提问作者Andrej
相关产品推荐
相关产品推荐

