AWS 凭证如何在 GitHub 操作中发挥作用?

How AWS Credentials works at GitHub Actions?

在我的单元测试中,我使用 aws-sdk 来测试需要一些凭据的 SES,我们在使用 GitHub 操作访问机密时遇到了问题。

一开始我尝试使用 github 工作流程中的 运行 命令将值设置为 ~/.aws/credentials

# .github/workflows/nodejs.yml
steps:
  ...
  - name: Unit Test
    run: |
      mkdir -p ~/.aws
      touch ~/.aws/credentials

      echo "[default]
      aws_access_key_id = ${{ secrets.AWS_ACCESS_KEY_ID }}
      aws_secret_access_key = ${{ secrets.AWS_SECRET_KEY_ID }}
      region = ${AWS_DEFAULT_REGION}

      [github]
      role_arn = arn:aws:iam::{accountID}:role/{role}
      source_profile = default" > ~/.aws/credentials 

      npm test
    env:
      AWS_DEFAULT_REGION: us-east-1
      CI: true

原来我的测试文件:

// ses.test.js
const AWS = require("aws-sdk")
const credentials = new AWS.SharedIniFileCredentials({ profile: "github" })
AWS.config.update({ credentials })
...

我尝试使用另一种方式在我的测试中获取凭据,但也不起作用:

const AWS = require("aws-sdk")
const credentials = new AWS.ChainableTemporaryCredentials({
  params: {RoleArn: "arn:aws:iam::{accountID}:role/{role}"},
  masterCredentials: new AWS.EnvironmentCredentials("AWS")
)}

AWS.config.update({ credentials })

最后我尝试创建一个自定义的动作(使用动作 js 库,如:@actions/core、@actions/io、@actions/exec),以获取 AWS 环境值并设置它在 ~/.aws/credentials,但也没有按预期工作

一种可行的方法是公开 AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY(出于安全目的,不使用 GitHub 操作机密,不理想)

有人知道 AWS 凭据如何在 GitHub Actions with secrets 中工作?

非常感谢您的关注。

幸运的是 aws-sdk 应该 automatically detect credentials 设置为环境变量并将它们用于请求

要在您的操作中访问机密,您需要在存储库中设置它们。然后您可以将它们作为环境变量公开给步骤。

有关详细信息,请参阅 GitHub Encrypted secrets

  1. 在 GitHub 上,导航到存储库的主页
  2. 在您的存储库名称下,单击 ⚙ 设置选项卡
  3. 存储库设置按钮
  4. 在左侧边栏中,点击 Secrets
  5. 在“名称”输入框中键入您的密钥的名称
  6. 键入您的密钥的值
  7. 点击添加密码

在您的情况下,您需要为 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 添加机密。

现在这些都已设置,您可以通过工作流 yaml 将这些值传递到操作中:

steps:
...
- name: Unit Test
  uses: ...
  env:
    AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
    AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
  run: ...

如果您可以接受命令行中的 运行ning aws,您可以设置以下 ENV 变量并仅使用 aws 命令而无需 运行 aws configure:

env:
  AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
  AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
  AWS_DEFAULT_REGION: us-east-1
  AWS_DEFAULT_OUTPUT: json

看看:https://github.com/aws-actions/configure-aws-credentials

它允许您配置 AWS 凭证和区域环境变量以用于其他 GitHub 操作。环境变量将由 AWS 开发工具包和 AWS CLI 检测以确定用于 AWS API 调用的凭证和区域。

避免使用长期和硬编码凭据。

configure-aws-credentials 操作提供了一种机制来配置 AWS 凭证和区域环境变量以用于其他 GitHub 操作。环境变量将由 AWS 开发工具包和 AWS CLI 检测以确定用于 AWS API 调用的凭证和区域。

我建议配置 configure-aws-credentials 以使用 OpenID Connect (OIDC)。这允许您的 GitHub Actions 工作流访问 AWS 中的资源,而无需将 AWS 凭证存储为长期 GitHub 秘密。 GitHub 在 AWS 中配置 OpenID Connect post 介绍了如何设置。

为了给你一个实际的例子,我设置了一个管道来将虚拟数据上传到 S3 存储桶。首先设置一个 OpenID Connect 提供商,以及 github 的角色以联合到您的 AWS 帐户中。 configure-aws-credentials 中的示例是用 CloudFormation 编写的,但我已将它们翻译成下面的 Python Cloud-Development-Kit(CDK)。确保更改角色条件以匹配您的存储库。

        github_oidc_provider = iam.OpenIdConnectProvider(
            self,
            "GithubOIDC",
            url="https://token.actions.githubusercontent.com",  
            thumbprints=["a031c46782e6e6c662c2c87c76da9aa62ccabd8e"],
            client_ids=[
                "sts.amazonaws.com" 
            ]
        )

        github_actions_role = iam.Role(
            self,
            "DeployToBucketRole",
            max_session_duration=cdk.Duration.seconds(3600),
            role_name="github-actions-role",
            description="Github actions deployment role to S3",
            assumed_by=iam.FederatedPrincipal(
                federated=github_oidc_provider.open_id_connect_provider_arn,
                conditions={
                    "StringLike": {
                        # <GITHUB USERNAME>/<YOUR REPO NAME>
                        "token.actions.githubusercontent.com:sub": 'repo:arbitraryrw/cdk-github-actions-demo:*' 
                    }
                },
                assume_role_action="sts:AssumeRoleWithWebIdentity"
            )
        )

        bucket = s3.Bucket(
            self,
            f"example_bucket",
            bucket_name="cdk-github-actions-demo",
            encryption=s3.BucketEncryption.S3_MANAGED,
            enforce_ssl=True,
            block_public_access=s3.BlockPublicAccess.BLOCK_ALL,
            removal_policy=cdk.RemovalPolicy.DESTROY,
            auto_delete_objects=True
        )

        # Give the role permissions to read / write to the bucket
        bucket.grant_read_write(github_actions_role)

然后您可以在您的管道和 运行 AWS CLI / SDK 命令中使用这些凭据引用它。请注意,代码段引用 Github Encrypted Secrets,我建议利用此功能:

name: Example CDK Pipeline

on:
  push:
    branches: [ main ]

jobs:
  build:
    name: Emulate build step
    runs-on: ubuntu-latest

    steps:
    - name: Checking out repository
      uses: actions/checkout@v2
    - name: "Upload artifacts"
      uses: actions/upload-artifact@v2
      with:
        name: build-artifacts
        path: ${{ github.workspace }}/resources

  deploy:
    needs: build
    name: Deploy build artifacts to S3
    runs-on: ubuntu-latest
    # These permissions are needed to interact with GitHub's OIDC Token endpoint.
    permissions:
      id-token: write
      contents: read

    steps:
    - name: "Download build artifacts"
      uses: actions/download-artifact@v2
      with:
        name: build-artifacts
        path: ${{ github.workspace }}/resources

    - name: Configure AWS credentials from Test account
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-region: us-east-1
        role-to-assume: ${{ secrets.AWS_ROLE_FOR_GITHUB }}
        role-session-name: GitHubActions
    - run: aws sts get-caller-identity
    - name: Copy files to the test website with the AWS CLI
      run: |
        aws s3 sync ./resources s3://${{ secrets.BUCKET_NAME }}

有关如何使用 CDK 进行设置的完整示例,您可以查看我设置的 cdk-github-actions-demo 存储库。