声明
本文由 🤖AI 协作完成, 内容已过实际测试.
1. 前言
在 CI/CD 流水线中访问 AWS 资源时,传统的做法是创建一个 IAM User,生成 Access Key ID 和 Secret Access Key (AK/SK),然后将其存储在 GitHub Secrets 中。
这种做法存在显著的安全隐患:
- 密钥泄露风险:如果 Secrets 管理不当或代码泄露,长期有效的密钥可能被盗用。
- 管理成本高:需要定期轮换密钥,维护麻烦。
更好的解决方案是使用 OpenID Connect (OIDC)。 通过配置 OIDC,GitHub Actions 可以在运行时向 AWS 申请临时的访问凭证。这是一种“无密钥 (Keyless)”的安全实践,完全避免了长期凭证的存储问题。
本文将详细介绍如何配置 AWS 和 GitHub Actions 来实现这一目标。
2. AWS 端配置:建立信任
我们需要在 AWS IAM 中配置一个“信任锚点”,告诉 AWS:“我信任 GitHub 的 OIDC 服务,并允许特定的 GitHub 仓库扮演我的 IAM 角色”。
第一步:创建 OIDC 身份提供商 (Identity Provider)
- 登录 AWS 控制台,进入 IAM 服务。
- 在左侧菜单点击 Identity providers (身份提供商),点击 Add provider。
- 配置如下信息:
- Provider type: 选择
OpenID Connect。 - Provider URL: 输入
https://token.actions.githubusercontent.com(必须完全一致,不要带多余的斜杠)。 - Audience: 输入
sts.amazonaws.com。
- Provider type: 选择
- 点击 Get thumbprint (获取指纹),AWS 会验证证书。
- 点击 Add provider 完成创建。
第二步:创建 IAM 角色 (IAM Role)
接下来,创建一个赋予 GitHub Action 权限的角色。
- 在 IAM 控制台,点击 Roles -> Create role。
- Trusted entity type 选择
Web identity。 - Identity provider 选择上一步创建的
token.actions.githubusercontent.com。 - Audience 选择
sts.amazonaws.com。 - GitHub organization/repository:此处可先跳过,我们稍后通过策略精确控制。
- 点击 Next,添加你需要的权限(例如
AmazonS3FullAccess或自定义策略)。 - 给角色起个名字(例如
GitHubAction-DeployRole),点击创建。
第三步:配置信任策略 (Trust Policy) —— 关键步骤
为了防止其他人的 GitHub 仓库冒充你的身份,我们需要严格限制信任范围。
- 进入刚创建的角色详情页,点击 Trust relationships 标签页。
- 点击 Edit trust policy。
- 将内容修改为以下 JSON。
注意:如果你使用的是 AWS 中国区(如
cn-northwest-1),ARN 的前缀是arn:aws-cn;如果是全球区,则是arn:aws。请根据实际情况修改。
1 | { |
配置说明:
sub(Subject) 字段决定了谁有权限。- 允许特定分支:
repo:org/repo:ref:refs/heads/main - 允许所有分支:
repo:org/repo:* - 允许特定 Tag:
repo:org/repo:ref:refs/tags/* - 允许组织下所有: repo:org/*
3. GitHub 端配置:编写流水线
第一步:准备 Role ARN
获取刚才创建的 IAM 角色 ARN,例如 arn:aws-cn:iam::123456789012:role/GitHubAction-DeployRole。
建议将其放入 GitHub 仓库的 Variables 或 Secrets 中,或者直接在 env 中定义。
第二步:编写 Workflow YAML
在 .github/workflows/xxx.yml 中,有两个关键点:
- Permissions: 必须声明
id-token: write,否则无法申请 OIDC 令牌。 - Action: 使用
aws-actions/configure-aws-credentials。
1 | name: AWS OIDC Deploy |
4. 原理解析
为什么这套流程是安全的?让我们通过流程图来看一下幕后发生了什么:
- 启动:GitHub Action 启动,检测到
permissions: id-token: write。 - 颁发令牌:GitHub OIDC Provider 生成一个 JWT 令牌,其中包含当前仓库的元数据(如
sub: repo:user/repo:ref:refs/heads/main)。 - 请求交换:
configure-aws-credentialsAction 拿着这个 JWT 令牌去请求 AWS STS 服务。 - 校验:AWS STS 进行双重检查:
- 验签:检查令牌是否由信任的 GitHub IdP 签发。
- 鉴权:检查 IAM Role 的 Trust Policy 中的
Condition是否匹配令牌中的sub信息。
- 授权:如果匹配,AWS 返回临时的 Access Key、Secret Key 和 Session Token。
- 执行:GitHub Action 使用这些临时凭证在有效期内操作 AWS 资源。
5. 常见问题 (FAQ)
Q: 报错
Not authorized to perform sts:AssumeRoleWithWebIdentity?- A: 检查 IAM Role 的 Trust Policy 中
sub字段是否拼写正确,GitHub 组织名和仓库名区分大小写。 - A: 检查
provider的 ARN 是否正确(注意全球区aws和中国区aws-cn的区别)。
- A: 检查 IAM Role 的 Trust Policy 中
Q: 临时凭证有效期是多久?
- A: 默认 1 小时。可以通过
role-duration-seconds参数调整,范围是 15 分钟到 12 小时。注意 IAM Role 本身也有一个“最大会话时长”设置,请求的时长不能超过该设置。
- A: 默认 1 小时。可以通过
Q: AWS 中国区有什么特别注意的?
- A: 主要是 ARN 格式(
arn:aws-cn)和 Region 代码(cn-northwest-1/cn-north-1)。OIDC Provider URL 依然是全球通用的token.actions.githubusercontent.com。
- A: 主要是 ARN 格式(
通过以上步骤,你就可以优雅地移除 GitHub Secrets 中的 AK/SK,实现更安全、更合规的云端部署流水线。