Skip to main content

在 Amazon Web Services 中配置 OpenID Connect

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

注意

GitHub Enterprise Server 目前不支持 GitHub 托管的运行器。

概述

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”。

  • 必须确保你的云提供商可以访问以下 OIDC 端点:

    • https://HOSTNAME/_services/token/.well-known/openid-configuration
    • https://HOSTNAME/_services/token/.well-known/jwks

    注意

    可以通过仅允许 AWS IP 地址范围来限制对 OIDC 终结点的访问。

    注意

    GitHub 本机不支持 AWS 会话标记。

将身份提供商添加到 AWS

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

  • 对于提供程序 URL:使用 https://HOSTNAME/_services/token
  • 对于“受众”:如果使用官方操作,请使用 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": {
    "HOSTNAME/_services/token:aud": "sts.amazonaws.com",
    "HOSTNAME/_services/token:sub": "repo:octo-org/octo-repo:ref:refs/heads/octo-branch"
  }
}

如果将工作流用于环境,则 sub 字段必须引用环境名称:repo:ORG-NAME/REPO-NAME:environment:ENVIRONMENT-NAME。 有关详细信息,请参阅“OpenID Connect 参考”。

注意

在工作流或 OIDC 策略中使用环境时,建议将保护规则添加到环境中以提高安全性。 例如,可以在环境中配置部署规则,以限制可以部署到环境或访问环境机密的分支和标记。 有关详细信息,请参阅“管理部署环境”。

JSON
"Condition": {
  "StringEquals": {
    "HOSTNAME/_services/token:aud": "sts.amazonaws.com",
    "HOSTNAME/_services/token: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 设置,以允许 GitHub 的 OIDC 提供者为每个运行创建 JSON Web 令牌。

注意

在工作流权限中设置 id-token: write 不会授予工作流修改或写入任何资源的权限。 这只会允许工作流为某个操作或步骤请求(提取)并使用(设置)OIDC 令牌。 然后,此令牌用于通过生存期较短的访问令牌向外部服务进行身份验证。

有关所需权限、配置示例和高级方案的详细信息,请参阅 OpenID Connect 参考

请求访问令牌

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

  • BUCKET-NAME:将其替换为 S3 存储桶的名称。
  • AWS-REGION:将其替换为 AWS 区域的名称。
  • ROLE-TO-ASSUME:将其替换为 AWS 角色。 例如: arn:aws:iam::1234567890:role/example-role
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 : "BUCKET-NAME"
  AWS_REGION : "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@v5
      - name: configure aws credentials
        uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502
        with:
          role-to-assume: ROLE-TO-ASSUME
          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 }}/

其他阅读材料