跳至主要内容

在 Amazon Web Services 中配置 OpenID Connect

在工作流中使用 OpenID Connect 向 Amazon Web Services 进行身份验证。

概述

OpenID Connect (OIDC) 允许你的 GitHub Actions 工作流访问 Amazon Web Services (AWS) 中的资源,而无需将 AWS 凭证存储为长期存在的 GitHub 机密。

本指南解释了如何配置 AWS 以信任 GitHub 的 OIDC 作为联合身份,并包含了一个工作流示例,用于 aws-actions/configure-aws-credentials,它使用令牌向 AWS 进行身份验证并访问资源。

注意:AWS 中不支持 OIDC 的自定义声明。

先决条件

  • 要了解 GitHub 如何使用 OpenID Connect (OIDC) 的基本概念及其架构和优势,请参阅“关于使用 OpenID Connect 进行安全强化”。

  • 在继续之前,你必须规划你的安全策略,以确保仅以可预测的方式分配访问令牌。要控制你的云提供商如何颁发访问令牌,你必须定义至少一个条件,以便不受信任的存储库无法为你的云资源请求访问令牌。有关更多信息,请参阅“关于使用 OpenID Connect 进行安全强化”。

将身份提供程序添加到 AWS

要将 GitHub OIDC 提供程序添加到 IAM,请参阅 AWS 文档

  • 对于提供程序 URL:如果使用 官方操作,请使用 https://token.actions.githubusercontent.com
  • 对于“受众”:如果使用 官方操作,请使用 sts.amazonaws.com

配置角色和信任策略

要配置 IAM 中的角色和信任,请参阅 AWS 文档“为 GitHub Actions 配置 AWS 凭证”和“为 GitHub OIDC 身份提供程序配置角色”。

注意:AWS 身份和访问管理 (IAM) 建议用户在信任 GitHub 的 OIDC 身份提供程序 (IdP) 的任何角色的信任策略中评估 IAM 条件键 token.actions.githubusercontent.com:sub。在角色信任策略中评估此条件键会限制哪些 GitHub 操作能够承担该角色。

编辑信任策略,将 sub 字段添加到验证条件。例如

JSON
"Condition": {
  "StringEquals": {
    "token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
    "token.actions.githubusercontent.com:sub": "repo:octo-org/octo-repo:ref:refs/heads/octo-branch"
  }
}

如果你使用带有环境的工作流,则 sub 字段必须引用环境名称:repo:OWNER/REPOSITORY:environment:NAME。有关更多信息,请参阅“关于使用 OpenID Connect 进行安全强化”。

注意:在工作流或 OIDC 策略中使用环境时,我们建议为环境添加保护规则以增强安全性。例如,你可以在环境上配置部署规则以限制哪些分支和标签可以部署到环境或访问环境机密。有关更多信息,请参阅“使用环境进行部署”。

JSON
"Condition": {
  "StringEquals": {
    "token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
    "token.actions.githubusercontent.com:sub": "repo:octo-org/octo-repo:environment:prod"
  }
}

在以下示例中,StringLike 与通配符运算符 (*) 一起使用,以允许来自 octo-org/octo-repo 组织和存储库的任何分支、请求合并分支或环境在 AWS 中承担角色。

JSON
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::123456123456:oidc-provider/token.actions.githubusercontent.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringLike": {
                    "token.actions.githubusercontent.com:sub": "repo:octo-org/octo-repo:*"
                },
                "StringEquals": {
                    "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
                }
            }
        }
    ]
}

更新 GitHub Actions 工作流

要为 OIDC 更新工作流,你需要对 YAML 进行两处更改

  1. 为令牌添加权限设置。
  2. 使用 aws-actions/configure-aws-credentials 操作将 OIDC 令牌 (JWT) 兑换为云访问令牌。

添加权限设置

 作业或工作流运行需要具有 id-token: writepermissions 设置。如果 id-tokenpermissions 设置为 readnone,你将无法请求 OIDC JWT ID 令牌。

id-token: write 设置允许使用以下方法之一从 GitHub 的 OIDC 提供程序请求 JWT

  • 在运行程序上使用环境变量 (ACTIONS_ID_TOKEN_REQUEST_URLACTIONS_ID_TOKEN_REQUEST_TOKEN)。
  • 从 Actions 工具包使用 getIDToken()

如果你需要为工作流获取 OIDC 令牌,则可以在工作流级别设置权限。例如

YAML
permissions:
  id-token: write # This is required for requesting the JWT
  contents: read  # This is required for actions/checkout

如果你只需要为单个作业获取 OIDC 令牌,则可以在该作业中设置此权限。例如

YAML
permissions:
  id-token: write # This is required for requesting the JWT

你可能需要根据工作流的要求在此处指定其他权限。

对于由与调用工作流相同的用户、组织或企业拥有的可重用工作流,可以在调用方的上下文中访问在可重用工作流中生成的 OIDC 令牌。对于企业或组织外部的可重用工作流,id-tokenpermissions 设置应在调用方工作流级别或调用可重用工作流的特定作业中明确设置为 write。这可确保仅在需要时才允许在调用方工作流中使用在可重用工作流中生成的 OIDC 令牌。

有关更多信息,请参阅“重用工作流”。

请求访问令牌

aws-actions/configure-aws-credentials 操作从 GitHub OIDC 提供程序接收 JWT,然后从 AWS 请求访问令牌。有关更多信息,请参阅 AWS 文档

  • <example-bucket-name>:在此处添加你的 S3 存储桶的名称。
  • <role-to-assume>:用你的 AWS 角色替换示例。
  • <example-aws-region>:在此处添加你的 AWS 区域的名称。
YAML
# Sample workflow to access AWS resources when workflow is tied to branch
# The workflow Creates static website using aws s3
name: AWS example workflow
on:
  push
env:
  BUCKET_NAME : "<example-bucket-name>"
  AWS_REGION : "<example-aws-region>"
# permission can be added at job level or workflow level
permissions:
  id-token: write   # This is required for requesting the JWT
  contents: read    # This is required for actions/checkout
jobs:
  S3PackageUpload:
    runs-on: ubuntu-latest
    steps:
      - name: Git clone the repository
        uses: actions/checkout@v4
      - name: configure aws credentials
        uses: aws-actions/configure-aws-credentials@v3
        with:
          role-to-assume: arn:aws:iam::1234567890:role/example-role
          role-session-name: samplerolesession
          aws-region: ${{ env.AWS_REGION }}
      # Upload a file to AWS s3
      - name:  Copy index.html to s3
        run: |
          aws s3 cp ./index.html s3://${{ env.BUCKET_NAME }}/

进一步阅读