为 GitHub Actions 工作流创建工作负载标识

已完成

了解工作负载标识的概念后,你可能想知道如何创建一个工作负载标识,然后将它链接到 GitHub Actions 部署工作流。 本单元介绍如何实现该目的。

创建 Microsoft Entra 应用程序

在上一单元中,你了解了工作负载标识需要在 Microsoft Entra ID 中创建应用程序注册。

注意

创建和修改应用程序注册时,需要在 Microsoft Entra ID 中具有相应的权限。 在一些组织中,可能需要管理员为你执行这些步骤。

创建应用程序注册时,需要指定显示名称。 显示名称是描述应用程序注册的用户可读名称。

提示

请为应用程序注册使用一个明确的描述性显示名称。 有必要帮助团队了解应用程序注册的用途,以便不会有人意外删除它或更改其权限。

下面是用于新建 Microsoft Entra ID 应用程序的示例 Azure CLI 命令:

az ad app create --display-name $applicationRegistrationName

下面是用于新建 Microsoft Entra ID 应用程序的示例 Azure PowerShell 命令:

New-AzADApplication -DisplayName $applicationRegistrationName

上述命令的输出包含一些重要的信息,其中包括:

  • 应用程序 ID:应用程序注册具有唯一标识符,通常称为“应用程序 ID”,有时也称为“客户端 ID”。 当工作流需要登录到 Azure 时,你会用到此标识符。
  • 对象 ID:应用程序注册具有对象 ID,它是 Microsoft Entra ID 分配的唯一标识符。 稍后会在本模块中看到一个示例,展示如何使用对象 ID。

创建应用程序注册时,通常只设置显示名称。 Azure 会自动分配其他名称和标识符。

注意

显示名称不是唯一的。 多个应用程序注册可能共享同一显示名称。 在使用应用程序注册的显示名称来标识它,从而对其授予权限时,请小心操作。 你可能会意外地向错误的应用程序注册授予权限。 最好改用其中一个唯一的标识符。

联合凭据

当标识需要与 Azure 通信时,它会登录到 Microsoft Entra ID。 应用程序注册本身不允许工作流或应用程序登录到 Azure。 首先需要分配一些凭据。 联合凭据是应用程序凭据的一种类型。 与大多数凭据不同,使用联合凭据时,无需管理密码或密钥等任何机密。

为部署工作流创建联合凭据时,可以有效地告知 Microsoft Entra ID 和 GitHub 相互信任。 这种信任被称为“联合身份验证”。

然后,当工作流尝试登录时,GitHub 会提供有关工作流运行的信息,让 Microsoft Entra ID 可以决定是否允许登录尝试。 GitHub 在每次登录尝试期间提供给 Microsoft Entra ID 的信息可包含以下字段:

  • GitHub 用户或组织名称。
  • GitHub 存储库名称。
  • 当前正在运行工作流的存储库分支。
  • 工作流作业面向的环境。 后续模块将对各种环境进行详细介绍。
  • 拉取请求的创建是否触发了工作流。

可以将 Microsoft Entra ID 配置为允许或拒绝来自 GitHub 的登录尝试,具体取决于前面列出的属性值。 例如,可以强制实施以下策略:

  • 仅当工作流从我的组织内的特定 GitHub 存储库运行时,才允许登录尝试。
  • 仅当工作流从我的组织内的特定 GitHub 存储库运行,且分支名称为“main”时,才允许登录尝试

下面是部署工作流如何使用工作负载标识和联合凭据登录的图示:

显示工作负载标识和联合凭据的登录过程的示意图。

登录过程中涉及的步骤如下:

  1. 当工作流需要与 Azure 通信时,GitHub 会通过安全的方式联系 Microsoft Entra ID 以请求访问令牌。 GitHub 提供有关 GitHub 组织 (my-github-user)、存储库 (my-repo) 以及正在运行工作流的分支 (main) 的信息。 其中还包括 Microsoft Entra ID 中的租户 ID、工作流标识的应用程序注册的应用程序 ID,以及工作流要部署到的 Azure 订阅 ID。

  2. Microsoft Entra ID 验证应用程序 ID,并检查 GitHub 组织、存储库和分支的应用程序中是否存在联合凭据。

  3. Microsoft Entra ID 确定请求有效后,会颁发访问令牌。 工作流在与 Azure 资源管理器通信时,使用该访问令牌。

创建联合凭据

使用 Azure CLI 时,可以通过创建 JSON 文件或变量来定义联合凭据。 例如,请看以下 JSON 文件:

{
  "name": "MyFederatedCredential",
  "issuer": "https://token.actions.githubusercontent.com",
  "subject": "repo:my-github-user/my-repo:ref:refs/heads/main",
  "audiences": [
    "api://AzureADTokenExchange"
  ]
}

在该文件中,subject 属性指定了联合凭据应当仅在工作流针对以下情况运行时才有效:

字段
GitHub 组织名称 my-github-user
GitHub 存储库名称 my-repo
分支名称 main

在 JSON 中创建策略并将其保存到名为“policy.json”的文件后,可以使用 Azure CLI 创建联合凭据:

az ad app federated-credential create \
  --id $applicationRegistrationObjectId \
  --parameters @policy.json

使用 Azure PowerShell 时,通过创建类似于以下内容的字符串来定义联合凭据:

$policy = "repo:my-github-user/my-repo:ref:refs/heads/main"

前面的字符串指定了应仅当工作流针对以下情况运行时,联合凭据才有效:

字段
GitHub 组织名称 my-github-user
GitHub 存储库名称 my-repo
分支名称 main

创建策略字符串后,可以使用 Azure PowerShell 创建联合凭据:

New-AzADAppFederatedCredential `
  -Name 'MyFederatedCredential' `
  -ApplicationObjectId $applicationRegistrationObjectId `
  -Issuer 'https://token.actions.githubusercontent.com' `
  -Audience 'api://AzureADTokenExchange' `
  -Subject $policy

管理工作负载标识的生命周期

有必要考虑所创建的每个工作负载标识的整个生命周期。 为部署工作流生成工作负载标识时,如果工作流最终被删除或不再使用,将会发生什么情况?

工作负载标识和联合凭据不会自动删除,因此你需要审核并删除这些旧数据。 即使部署工作流的工作负载标识没有可以重复使用的机密凭据,但当它们不再需要时,最好还是将其删除。 这样一来,就不可能出现某人使用同一名称创建另一个 GitHub 存储库,并意外获得对你的 Azure 环境的访问权限的情况。

最佳做法是将工作负载标识记录在你和团队可轻松访问的位置。 为每个工作负载标识包含以下信息:

  • 关键的标识信息,例如其名称和应用程序 ID
  • 其用途
  • 它是谁创建的、谁负责管理它,以及如果有问题,谁可能提供解答
  • 它需要的权限,以及为何需要这些权限的明确理由
  • 其预期生存期

应定期审核工作负载标识,确保它们仍然在使用,并且为它们分配的权限仍然是正确的。