Help us learn about your current experience with the documentation. Take the survey.

在 Azure 中配置 OpenID Connect 以获取临时凭证

  • Tier: Free, Premium, Ultimate
  • Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated

CI_JOB_JWT_V2GitLab 15.9 中已被弃用 并计划在 GitLab 17.0 中移除。请改用 ID tokens

本教程演示如何在 GitLab CI/CD 作业中使用 JSON Web Token (JWT) 从 Azure 获取临时凭证,无需存储密钥。

开始之前,请配置 GitLab 和 Azure 之间的身份联合的 OpenID Connect (OIDC)。 有关在 GitLab 中使用 OIDC 的更多信息,请阅读 连接到云服务

先决条件:

  • 对现有 Azure 订阅具有 Owner 访问权限。
  • 对相应的 Azure Active Directory 租户至少具有 Application Developer 访问权限。
  • 本地安装 Azure CLI。 或者,您可以使用 Azure Cloud Shell 完成以下所有步骤。
  • 您的 GitLab 实例必须可以通过互联网公开访问,因为 Azure 需要连接到 GitLab OIDC 端点。
  • 一个 GitLab 项目。

完成本教程的步骤:

  1. 创建 Azure AD 应用程序和服务主体
  2. 创建 Azure AD 联合身份凭证
  3. 授予服务主体的权限
  4. 获取临时凭证

有关 Azure 身份联合的更多信息,请参阅 工作负载身份联合

创建 Azure AD 应用程序和服务主体

要创建 Azure AD 应用程序 和服务主体:

  1. 在 Azure CLI 中,创建 AD 应用程序:

    appId=$(az ad app create --display-name gitlab-oidc --query appId -otsv)

    保存 appId(应用程序客户端 ID)输出,因为稍后需要它 来配置您的 GitLab CI/CD 管道。

  2. 创建相应的 服务主体

    az ad sp create --id $appId --query appId -otsv

除了 Azure CLI,您还可以 使用 Azure门户创建这些资源

创建 Azure AD 联合身份凭证

为之前创建的 Azure AD 应用程序 为 <mygroup>/<myproject> 中的特定分支创建联合身份凭证:

objectId=$(az ad app show --id $appId --query id -otsv)

cat <<EOF > body.json
{
  "name": "gitlab-federated-identity",
  "issuer": "https://gitlab.example.com",
  "subject": "project_path:<mygroup>/<myproject>:ref_type:branch:ref:<branch>",
  "description": "GitLab 服务账户联合身份",
  "audiences": [
    "https://gitlab.example.com"
  ]
}
EOF

az rest --method POST --uri "https://graph.microsoft.com/beta/applications/$objectId/federatedIdentityCredentials" --body @body.json

如果遇到与 issuersubjectaudiences 值相关的问题,请参阅 故障排除 详情。

可选地,您现在可以从 Azure门户验证 Azure AD 应用程序和 Azure AD 联合 身份凭证:

  1. 打开 Azure Active Directory 应用程序注册 视图,通过搜索显示名称 gitlab-oidc 选择相应的应用程序注册。
  2. 在概览页面中,您可以验证 Application (client) IDObject IDTenant ID 等详细信息。
  3. Certificates & secrets 下,转到 Federated credentials 查看 您的 Azure AD 联合身份凭证。

为任意分支或任意标签创建凭证

要为任意分支或标签(通配符匹配)创建凭证,您可以使用 灵活的联合身份凭证

<mygroup>/<myproject> 中的所有分支:

objectId=$(az ad app show --id $appId --query id -otsv)

cat <<EOF > body.json
{
  "name": "gitlab-federated-identity",
  "issuer": "https://gitlab.example.com",
  "subject": null,
  "claimsMatchingExpression": {
    "value": "claims['sub'] matches 'project_path:<mygroup>/<myproject>:ref_type:branch:ref:*'",
    "languageVersion": 1
  },
  "description": "GitLab 服务账户联合身份",
  "audiences": [
    "https://gitlab.example.com"
  ]
}
EOF

az rest --method POST --uri "https://graph.microsoft.com/beta/applications/$objectId/federatedIdentityCredentials" --body @body.json

<mygroup>/<myproject> 中的所有标签:

objectId=$(az ad app show --id $appId --query id -otsv)

cat <<EOF > body.json
{
  "name": "gitlab-federated-identity",
  "issuer": "https://gitlab.example.com",
  "subject": null,
  "claimsMatchingExpression": {
    "value": "claims['sub'] matches 'project_path:<mygroup>/<myproject>:ref_type:tag:ref:*'",
    "languageVersion": 1
  },
  "description": "GitLab 服务账户联合身份",
  "audiences": [
    "https://gitlab.example.com"
  ]
}
EOF

az rest --method POST --uri "https://graph.microsoft.com/beta/applications/$objectId/federatedIdentityCredentials" --body @body.json

为服务主体授予权限

创建凭证后,使用 role assignment 为之前的服务主体授予权限,使其能够访问 Azure 资源:

az role assignment create --assignee $appId --role Reader --scope /subscriptions/<subscription-id>

您可以在以下位置找到您的订阅 ID:

上述命令授予对整个订阅的只读权限。有关在您的组织上下文中应用最小权限原则的更多信息,请阅读 Azure AD 角色最佳实践

获取临时凭证

配置 Azure AD 应用程序和联合身份凭证后, CI/CD 作业可以使用 Azure CLI 获取临时凭证:

default:
  image: mcr.microsoft.com/azure-cli:latest

variables:
  AZURE_CLIENT_ID: "<client-id>"
  AZURE_TENANT_ID: "<tenant-id>"

auth:
  id_tokens:
    GITLAB_OIDC_TOKEN:
      aud: https://gitlab.com
  script:
    - az login --service-principal -u $AZURE_CLIENT_ID -t $AZURE_TENANT_ID --federated-token $GITLAB_OIDC_TOKEN
    - az account show

CI/CD 变量包括:

故障排除

“未找到匹配的联合身份记录”

如果您收到错误 ERROR: AADSTS70021: No matching federated identity record found for presented assertion. 您应该验证:

  • Azure AD 联合身份凭证中定义的 Issuer,例如 https://gitlab.com 或您自己的 GitLab URL。
  • Azure AD 联合身份凭证中定义的 Subject identifier,例如 project_path:<mygroup>/<myproject>:ref_type:branch:ref:<branch>
    • 对于 gitlab-group/gitlab-project 项目和 main 分支,它将是: project_path:gitlab-group/gitlab-project:ref_type:branch:ref:main
    • 正确的 mygroupmyproject 值可以通过访问 GitLab 项目时的 URL 或在项目概览页面右上角选择 Code 来获取。
  • Azure AD 联合身份凭证中定义的 Audience,例如 https://gitlab.com 或您自己的 GitLab URL。

您可以从 Azure门户查看这些设置,以及您的 AZURE_CLIENT_IDAZURE_TENANT_ID CI/CD 变量:

  1. 打开 Azure Active Directory 应用程序注册 视图,通过搜索显示名称 gitlab-oidc 选择相应的应用程序注册。
  2. 在概览页面中,您可以验证 Application (client) IDObject IDTenant ID 等详细信息。
  3. Certificates & secrets 下,转到 Federated credentials 查看 您的 Azure AD 联合身份凭证。

有关更多详细信息,请参阅 连接到云服务

“请求外部 OIDC 端点失败” 消息

如果您收到错误 ERROR: AADSTS501661: Request to External OIDC endpoint failed. 您应该验证您的 GitLab 实例是否可以从互联网公开访问。

Azure 必须能够访问以下 GitLab 端点才能通过 OIDC 进行身份验证:

  • GET /.well-known/openid-configuration
  • GET /oauth/discovery/keys

如果您更新了防火墙但仍收到此错误,清除 Redis 缓存 然后重试。

“未找到匹配的联合身份记录用于提供的断言受众” 消息

如果您收到错误 ERROR: AADSTS700212: No matching federated identity record found for presented assertion audience 'https://gitlab.com' 您应该验证您的 CI/CD 作业是否使用了正确的 aud 值。

aud 值应与用于 创建联合身份凭证 的受众匹配。