使用 ID 令牌的 OpenID Connect (OIDC) 身份验证

您可以使用极狐GitLab CI/CD 的 ID 令牌对第三方服务进行身份验证。

ID 令牌

ID 令牌是可以添加到极狐GitLab CI/CD 作业的 JSON Web 令牌 (JWT)。它们可用于第三方服务的 OIDC 身份验证,并被 secrets 关键字用于与 HashiCorp Vault 进行身份验证。

ID 令牌在 .gitlab-ci.yml 中配置。例如:

job_with_id_tokens:
  id_tokens:
    FIRST_ID_TOKEN:
      aud: https://first.service.com
    SECOND_ID_TOKEN:
      aud: https://second.service.com
  script:
    - first-service-authentication-script.sh $FIRST_ID_TOKEN
    - second-service-authentication-script.sh $SECOND_ID_TOKEN

在此示例中,这两个令牌具有不同的 aud 声明。第三方服务可以配置为拒绝没有匹配其绑定受众的 aud 声明的令牌。您可以使用此功能来减少令牌可以用来进行身份验证的服务数量,降低令牌泄露的严重性。

令牌负载

每个 ID 令牌中包含以下标准声明:

字段 描述
iss 令牌的颁发者,极狐GitLab 实例的域名(issuer 声明)。
sub project_path:{group}/{project}:ref_type:{type}:ref:{branch_name}subject 声明)。
aud 令牌的目标受众(audience 声明)。在 ID tokens 配置中指定。默认情况下为极狐GitLab 实例的域名。
exp 到期时间(expiration time 声明)。
nbf 令牌生效的时间(not before 声明)。
iat JWT 颁发时间(issued at 声明)。
jti 令牌的唯一标识符(JWT ID 声明)。

该令牌还包括极狐GitLab 提供的自定义声明:

字段 何时有效 描述
namespace_id 总是 使用它来按 ID 将范围限定为群组或用户级别的命名空间。
namespace_path 总是 使用它来按路径将范围限定为群组或用户级别的命名空间。
project_id 总是 使用它来按 ID 确定项目范围。
project_path 总是 使用它来按路径确定项目范围。
user_id 总是 执行作业的用户 ID。
user_login 总是 执行作业的用户的用户名。
user_email 总是 执行作业的用户的电子邮件。
pipeline_id 总是 流水线的 ID。
pipeline_source 总是 流水线源
job_id 总是 作业的 ID。
ref 总是 作业的 Git ref。
ref_type 总是 Git ref 类型,branchtag
ref_protected 总是 如果 Git ref 受保护,则为 true,否则为 false
environment 作业指定一个环境时 此作业部署到的环境(引入于 13.9 版本)。
environment_protected 作业指定一个环境时 如果部署的环境受到保护,则为 true,否则为 false(引入于 13.9 版本)。
deployment_tier 作业指定一个环境时 作业指定的环境的部署级别(引入于 15.2 版本)。
{
  "namespace_id": "72",
  "namespace_path": "my-group",
  "project_id": "20",
  "project_path": "my-group/my-project",
  "user_id": "1",
  "user_login": "sample-user",
  "user_email": "sample-user@example.com",
  "pipeline_id": "574",
  "pipeline_source": "push",
  "job_id": "302",
  "ref": "feature-branch-1",
  "ref_type": "branch",
  "ref_protected": "false",
  "environment": "test-environment2",
  "environment_protected": "false",
  "deployment_tier": "testing",
  "jti": "235b3a54-b797-45c7-ae9a-f72d7bc6ef5b",
  "iss": "https://gitlab.example.com",
  "iat": 1681395193,
  "nbf": 1681395188,
  "exp": 1681398793,
  "sub": "project_path:my-group/my-project:ref_type:branch:ref:feature-branch-1",
  "aud": "https://vault.example.com"
}

ID 令牌使用 RS256 编码并使用专用私钥签名。如果指定,则令牌的到期时间设置为作业的超时时间,如果未指定超时时间,则设置为 5 分钟。

手动 ID 令牌身份验证

您可以使用 ID 令牌通过第三方服务进行 OIDC 身份验证。例如:

manual_authentication:
  variables:
    VAULT_ADDR: http://vault.example.com:8200
  image: vault:latest
  id_tokens:
    VAULT_ID_TOKEN:
      aud: http://vault.example.com:8200
  script:
    - export VAULT_TOKEN="$(vault write -field=token auth/jwt/login role=myproject-example jwt=$VAULT_ID_TOKEN)"
    - export PASSWORD="$(vault kv get -field=password secret/myproject/example/db)"
    - my-authentication-script.sh $VAULT_TOKEN $PASSWORD

使用 HashiCorp Vault 进行自动 ID 令牌身份验证

您可以使用 ID 令牌通过 secrets 关键字自动从 HashiCorp Vault 获取 secrets。

启用自动 ID 令牌身份验证

启用自动 ID 令牌身份验证:

  1. 在顶部栏中,选择 主菜单 > 项目 并找到您的项目。
  2. 在左侧边栏中,选择 设置 > CI/CD
  3. 展开 令牌访问
  4. 限制 JSON Web 令牌 (JWT) 访问 切换为启用。

配置自动 ID 令牌身份验证

如果定义了一个 ID 令牌,secrets 关键字会自动使用它来对 Vault 进行身份验证。例如:

job_with_secrets:
  id_tokens:
    VAULT_ID_TOKEN:
      aud: https://example.vault.com
  secrets:
    PROD_DB_PASSWORD:
      vault: example/db/password # authenticates using $VAULT_ID_TOKEN
  script:
    - access-prod-db.sh --token $PROD_DB_PASSWORD

如果定义了多个 ID 令牌,请使用 token 关键字指定应使用哪个令牌。例如:

job_with_secrets:
  id_tokens:
    FIRST_ID_TOKEN:
      aud: https://first.service.com
    SECOND_ID_TOKEN:
      aud: https://second.service.com
  secrets:
    FIRST_DB_PASSWORD:
      vault: first/db/password
      token: $FIRST_ID_TOKEN
    SECOND_DB_PASSWORD:
      vault: second/db/password
      token: $SECOND_ID_TOKEN
  script:
    - access-first-db.sh --token $FIRST_DB_PASSWORD
    - access-second-db.sh --token $SECOND_DB_PASSWORD