Skip to main content

在云提供商中配置 OpenID Connect

在工作流程中使用 OpenID Connect 向云提供商进行身份验证。

概述

OpenID Connect (OIDC) 允许您的 GitHub Actions 工作流程访问云提供商中的资源,而无需将任何凭据存储为长期 GitHub 机密。

要使用 OIDC,需要先配置云提供商信任 GitHub 的 OIDC 作为联合身份,然后必须更新工作流程以使用令牌进行验证。

先决条件

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

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

更新 GitHub Actions 工作流程

要更新 OIDC 的工作流程,您需要对 YAML 进行两项更改:

  1. 为令牌添加权限设置。
  2. 使用云提供商的官方操作将 OIDC 令牌 (JWT) 交换为云访问令牌。

如果您的云提供商尚未提供官方操作,您可以更新工作流程以手动执行这些步骤。

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

添加权限设置

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

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

  • 在运行器上使用环境变量(ACTIONS_ID_TOKEN_REQUEST_URLACTIONS_ID_TOKEN_REQUEST_TOKEN)。
  • 使用“操作”工具包中的 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 令牌按预期在调用方工作流中使用。

有关详细信息,请参阅“重新使用工作流”。

使用官方操作

如果您的云提供商已创建将 OIDC 与 GitHub Actions 结合使用的官方操作,它将允许您轻松地将 OIDC 令牌交换为访问令牌。 然后,可以更新工作流程,以便在访问云资源时使用此令牌。

使用自定义操作

如果您的云提供商没有官方操作,或者您更喜欢创建自定义脚本,则可以手动向 GitHub的 OIDC 提供商请求 JSON Web 令牌 (JWT)。

如果您没有使用官方操作,则 GitHub 建议您使用 Actions 核心工具包。 也可使用以下环境变量来检索令牌:ACTIONS_RUNTIME_TOKENACTIONS_ID_TOKEN_REQUEST_URL

要使用此方法更新工作流程,您需要对 YAML 进行三项更改:

  1. 为令牌添加权限设置。
  2. 添加从 GitHub 的 OIDC 提供商请求 OIDC 令牌的代码。
  3. 添加用于将 OIDC 令牌与您的云提供商交换为访问令牌的代码。

使用 Actions 核心工具包请求 JWT

以下示例演示如何将 actions/github-scriptcore 工具包一起使用,从 GitHub 的 OIDC 提供商那里请求 JWT。 有关详细信息,请参阅“创建 JavaScript 操作”。

jobs:
  job:
    environment: Production
    runs-on: ubuntu-latest
    steps:
    - name: Install OIDC Client from Core Package
      run: npm install @actions/core@1.6.0 @actions/http-client
    - name: Get Id Token
      uses: actions/github-script@v6
      id: idtoken
      with:
        script: |
          const coredemo = require('@actions/core')
          let id_token = await coredemo.getIDToken()
          coredemo.setOutput('id_token', id_token)

使用环境变量请求 JWT

下面的示例演示如何使用环境变量来请求 JSON Web 令牌。

对于部署作业,需要使用 actions/github-scriptcore 工具包来定义令牌设置。 有关详细信息,请参阅“创建 JavaScript 操作”。

例如:

jobs:
  job:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/github-script@v6
      id: script
      timeout-minutes: 10
      with:
        debug: true
        script: |
          const token = process.env['ACTIONS_RUNTIME_TOKEN']
          const runtimeUrl = process.env['ACTIONS_ID_TOKEN_REQUEST_URL']
          core.setOutput('TOKEN', token.trim())
          core.setOutput('IDTOKENURL', runtimeUrl.trim())

然后,可使用 curl 从 GitHub OIDC 提供商那里检索 JWT。 例如:

    - run: |
        IDTOKEN=$(curl -H "Authorization: bearer  ${{steps.script.outputs.TOKEN}}" ${{steps.script.outputs.IDTOKENURL}}  -H "Accept: application/json; api-version=2.0" -H "Content-Type: application/json" -d "{}" | jq -r '.value')
        echo $IDTOKEN
        jwtd() {
            if [[ -x $(command -v jq) ]]; then
                jq -R 'split(".") | .[0],.[1] | @base64d | fromjson' <<< "${1}"
                echo "Signature: $(echo "${1}" | awk -F'.' '{print $3}')"
            fi
        }
        jwtd $IDTOKEN
        echo "idToken=${IDTOKEN}" >> $GITHUB_OUTPUT
      id: tokenid

从云提供商获取访问令牌

您需要向云提供商提供 OIDC JSON Web 令牌,以便获取访问令牌。

对于每个部署,您的工作流程必须使用云登录操作(或自定义脚本),以提取 OIDC 令牌并将其提供给您的云提供商。 然后,云提供商验证令牌中的声明;如果成功,它将提供仅可用于该作业运行的云访问令牌。 然后,作业中的后续操作可以使用提供的访问令牌连接到云并部署到其资源。

将 OIDC 令牌交换为访问令牌的步骤因每个云提供商而异。

访问云提供商中的资源

获取访问令牌后,可以使用特定的云操作或脚本向云提供商进行身份验证并部署到其资源。 对于每个云提供商,这些步骤可能会有所不同。 此外,此访问令牌的默认过期时间可能因每个云而异,并且可以在云提供商端进行配置。

延伸阅读