概述
OpenID Connect (OIDC) 允许您的 GitHub Actions 工作流访问云提供商中的资源,无需将任何凭据存储为长期存在的 GitHub 密钥。
要使用 OIDC,您首先需要配置您的云提供商以信任 GitHub 的 OIDC 作为联合身份,然后必须更新您的工作流以使用令牌进行身份验证。
先决条件
-
要了解 GitHub 如何使用 OpenID Connect (OIDC) 的基本概念及其架构和优势,请参阅“关于使用 OpenID Connect 进行安全加固”。
-
在继续之前,您必须规划您的安全策略,以确保仅以可预测的方式分配访问令牌。要控制云提供商如何发出访问令牌,您**必须**定义至少一个条件,以便不受信任的存储库无法请求云资源的访问令牌。有关更多信息,请参阅“关于使用 OpenID Connect 进行安全加固”。
更新您的 GitHub Actions 工作流
要更新工作流以使用 OIDC,您需要对 YAML 进行两处更改
- 为令牌添加权限设置。
- 使用云提供商提供的官方操作将 OIDC 令牌 (JWT) 交换为云访问令牌。
如果您的云提供商尚未提供官方操作,您可以更新您的工作流以手动执行这些步骤。
注意
当在工作流或 OIDC 策略中使用环境时,我们建议向环境添加保护规则以增强安全性。例如,您可以配置环境上的部署规则以限制哪些分支和标签可以部署到环境或访问环境密钥。有关更多信息,请参阅“管理部署环境”。
添加权限设置
作业或工作流运行需要一个包含 id-token: write
的 permissions
设置,以允许 GitHub 的 OIDC 提供程序为每次运行创建 JSON Web 令牌。如果 id-token
的 permissions
未设置为 write
,则您将无法请求 OIDC JWT ID 令牌,但是此值并不意味着授予任何资源的写入访问权限,而只是能够为操作或步骤获取和设置 OIDC 令牌,以启用使用短期访问令牌进行身份验证。任何实际的信任设置都是使用 OIDC 声明定义的,有关更多信息,请参阅 "使用 OpenID Connect 加强安全性"。
id-token: write
设置允许使用以下方法之一从 GitHub 的 OIDC 提供程序请求 JWT
- 在运行器上使用环境变量(
ACTIONS_ID_TOKEN_REQUEST_URL
和ACTIONS_ID_TOKEN_REQUEST_TOKEN
)。 - 使用 Actions 工具包中的
getIDToken()
。
如果您需要为工作流获取 OIDC 令牌,则可以在工作流级别设置权限。例如
permissions: id-token: write # This is required for requesting the JWT contents: read # This is required for actions/checkout
permissions:
id-token: write # This is required for requesting the JWT
contents: read # This is required for actions/checkout
如果您只需要为单个作业获取 OIDC 令牌,则可以在该作业中设置此权限。例如
permissions: id-token: write # This is required for requesting the JWT
permissions:
id-token: write # This is required for requesting the JWT
根据工作流的要求,您可能需要在此处指定其他权限。
对于与调用工作流属于同一用户、组织或企业的可重用工作流,可以在调用方的上下文中访问在可重用工作流中生成的 OIDC 令牌。对于企业或组织外部的可重用工作流,应在调用工作流级别或在调用可重用工作流的特定作业中将 id-token
的 permissions
设置显式设置为 write
。这可确保仅在预期时才允许在调用工作流中使用在可重用工作流中生成的 OIDC 令牌。
有关更多信息,请参阅 "重用工作流"。
使用官方操作
如果您的云提供商已创建用于将 OIDC 与 GitHub Actions 配合使用的官方操作,则它将允许您轻松地将 OIDC 令牌交换为访问令牌。然后,您可以更新您的工作流以在访问云资源时使用此令牌。
例如,阿里云创建了 aliyun/configure-aliyun-credentials-action
以集成使用 OIDC 与 GitHub。
使用自定义操作
如果您的云提供商没有官方操作,或者您更喜欢创建自定义脚本,则可以手动从 GitHub 的 OIDC 提供程序请求 JSON Web 令牌 (JWT)。
如果您未使用官方操作,则 GitHub 建议您使用 Actions 核心工具包。或者,您可以使用以下环境变量来检索令牌:ACTIONS_ID_TOKEN_REQUEST_TOKEN
、ACTIONS_ID_TOKEN_REQUEST_URL
。
要使用此方法更新您的工作流,您需要对 YAML 进行三个更改
- 为令牌添加权限设置。
- 添加从 GitHub 的 OIDC 提供程序请求 OIDC 令牌的代码。
- 添加将 OIDC 令牌与您的云提供商交换为访问令牌的代码。
使用 Actions 核心工具包请求 JWT
以下示例演示了如何使用 actions/github-script
和 core
工具包从 GitHub 的 OIDC 提供程序请求 JWT。有关更多信息,请参阅 "创建 JavaScript 操作"。
jobs:
job:
environment: Production
runs-on: ubuntu-latest
steps:
- name: Install OIDC Client from Core Package
run: npm install @actions/[email protected] @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-script
和 core
工具包定义令牌设置。有关更多信息,请参阅 "创建 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 令牌交换为访问令牌的步骤因云提供商而异。
访问云提供商中的资源
获得访问令牌后,您可以使用特定的云操作或脚本对云提供商进行身份验证并将其部署到其资源。这些步骤可能因云提供商而异。
例如,阿里云维护着自己的 OIDC 身份验证说明。有关更多信息,请参阅阿里云文档中的 基于 OIDC 的 SSO 概述。
此外,此访问令牌的默认过期时间可能因每个云而异,并且可以在云提供商端进行配置。