Microsoft Entra 联合身份凭据通过匹配 GitHub 签发的 OpenID Connect (OIDC) 令牌中的主题(sub)声明,来信任 GitHub Actions 工作流。 GitHub的原始主题是从存储库和所有者名称生成的,可以重命名、传输或重复使用。 信任基于名称的主体的联合身份凭据会面临 主体回收 的风险,即之后不同的存储库或所有者可能会生成与您的凭据相匹配的令牌。 若要了解有关此风险的详细信息,请参阅 联合标识凭据中的可变主题。
GitHub现在提供一种不可变的主题格式,用于嵌入不可变存储库和所有者 ID。 本文介绍如何在不停机的情况下将现有联合标识凭据迁移到该格式:为不可变使用者创建新凭据、在GitHub中启用不可变主题、验证工作流,然后删除旧凭据。
了解不可变的主题格式
GitHub的原始主题基于名称。 例如,在 main 存储库分支上运行的 contoso/payments-api 工作流将生成以下主题:
repo:contoso/payments-api:ref:refs/heads/main
不可变格式保留名称,但追加不可变所有者 ID 和存储库 ID,用符号 @ 分隔:
repo:<owner>@<owner_id>/<repo>@<repo_id>:ref:refs/heads/main
所有者 ID 和存储库 ID 分配一次且永不重复使用,因此重命名、传输或重新创建存储库不会更改它们。 信任不可变主体的联合标识凭据将一直绑定到原始存储库。
注释
不可变的主题适用于 GitHub.com。 它们在 GitHub Enterprise Server 上不可用。
获取不可变存储库和所有者 ID
若要生成不可变的主题,请从GitHub获取数字所有者 ID 和存储库 ID。 这些 ID 可通过GitHub的 OIDC 设置和 REST API 获得。
合并名称和 ID 以形成不可变的主题。 例如,如果所有者 contoso 具有 ID 5544123 ,并且存储库 payments-api 具有 ID 821093847,则分支的 main 不可变主题为:
repo:contoso@5544123/payments-api@821093847:ref:refs/heads/main
为不可变主体创建联合身份凭据
为该不可变主体在现有凭据之外再创建一个新的联合身份凭据。 将这两个凭据都保留到位,使工作流在验证更改时保持运行。
使用生成的不可变主题将凭据正文保存到文件,例如 credential.json:
{
"name": "payments-api-main-immutable",
"issuer": "https://token.actions.githubusercontent.com",
"subject": "repo:contoso@5544123/payments-api@821093847:ref:refs/heads/main",
"audiences": ["api://AzureADTokenExchange"]
}
使用Azure CLI创建凭据:
az ad app federated-credential create \
--id <application-object-id> \
--parameters ./credential.json
将 <application-object-id> 替换为你的应用注册的对象 ID。 为工作流呈现的每个主题创建一个凭据,例如不同的分支或环境。
将所需的声明添加到灵活的联合标识凭据
对于GitHub,灵活的联合标识凭据必须与声明和以下一个或两个附加声明匹配sub:
-
repository_id标识工作流运行位置的存储库。 -
repository_owner_id标识存储库所有者。
无论使用基于名称、自定义格式还是不可变格式,都需要 sub 这些附加声明。 包括表示预期信任边界的声明。
以下凭据与不可变主题匹配,并单独验证存储库:
{
"name": "github-repository-immutable",
"issuer": "https://token.actions.githubusercontent.com",
"claimsMatchingExpression": {
"value": "claims['sub'] matches 'repo:octo-org@123456/octo-repo@456789:*' and claims['repository_id'] eq '456789'",
"languageVersion": 1
},
"audiences": ["api://AzureADTokenExchange"]
}
若要要求存储库与特定所有者一起保留,还需匹配 repository_owner_id:
{
"name": "github-repository-owner-immutable",
"issuer": "https://token.actions.githubusercontent.com",
"claimsMatchingExpression": {
"value": "claims['sub'] matches 'repo:octo-org@123456/octo-repo@456789:*' and claims['repository_id'] eq '456789' and claims['repository_owner_id'] eq '123456'",
"languageVersion": 1
},
"audiences": ["api://AzureADTokenExchange"]
}
将示例值替换为 GitHub OIDC 令牌中的 ID。 GitHub在令牌中提供repository_id并repository_owner_id作为单独的声明。
在 GitHub 中启用不可变主题
从存储库或组织 OIDC 设置中将存储库选择为不可变的主题格式。 GitHub 同时提供了 UI 和 API 控制功能,以及一个用于预览工作流生成的主题的端点,以便你在依赖该值之前先进行确认。 有关当前步骤,请参阅 GitHub OpenID Connect 参考。
选择加入后,GitHub颁发使用配置凭据匹配的不可变主题的令牌。
注释
从 2026 年 7 月 15 日开始,GitHub会自动将不可变格式应用于创建、重命名或传输的存储库。 现有存储库将继续使用基于名称的格式,直到你选择启用。 有关详细信息,请参阅 GitHub Changelog 中GitHub Actions OIDC 令牌的不可变使用者声明。
验证并删除旧凭据
新凭据到位并GitHub发出不可变主题后,确认工作流正常工作,然后停用旧凭据:
运行GitHub Actions工作流,并确认它通过新凭据对Microsoft Entra进行身份验证。
在工作流针对不可变主体成功运行后,请删除旧的基于名称的凭据,以确保不再保留任何可变凭据:
az ad app federated-credential delete \ --id <application-object-id> \ --federated-credential-id <old-credential-id>将
<application-object-id>替换为你的应用注册的对象 ID,并将<old-credential-id>替换为旧的基于名称的凭据的 ID。
移除旧凭据会消除悬空的可变主体信任关系,并完成迁移。