使用 ID 令牌进行 OIDC 认证
- Tier: 基础版, 专业版, 旗舰版
- Offering: JihuLab.com, 私有化部署
History
- 引入于极狐GitLab 15.7。
您可以使用极狐GitLab CI/CD 的 ID 令牌 进行第三方服务的身份验证。
ID 令牌
ID 令牌 是可以添加到极狐GitLab CI/CD 作业中的 JSON Web Tokens (JWTs)。它们可以用于与第三方服务的 OIDC 身份验证,并由 secrets 关键字用于与 HashiCorp Vault 进行身份验证。
ID 令牌在 .gitlab-ci.yml 中配置。例如:
yaml1job_with_id_tokens: 2 id_tokens: 3 FIRST_ID_TOKEN: 4 aud: https://first.service.com 5 SECOND_ID_TOKEN: 6 aud: https://second.service.com 7 script: 8 - first-service-authentication-script.sh $FIRST_ID_TOKEN 9 - second-service-authentication-script.sh $SECOND_ID_TOKEN
在这个例子中,两个令牌有不同的 aud 声明。可以配置第三方服务以拒绝没有与它们绑定的受众匹配的 aud 声明的令牌。使用此功能来减少令牌可以进行身份验证的服务数量。这减少了令牌被泄露的严重性。
令牌负载
每个 ID 令牌中包含以下标准声明:
| 字段 | 描述 |
|---|---|
| iss | 令牌的发行者,即极狐GitLab 实例的域 ("issuer" 声明)。 |
| sub | 令牌的主题 ("subject" 声明)。默认为 project_path:{group}/{project}:ref_type:{type}:ref:{branch_name}。可以使用项目 API配置项目。 |
| aud | 令牌的预期受众 ("audience" 声明)。在ID 令牌配置中指定。默认情况下为极狐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 | 总是 | 执行作业的用户电子邮件。 |
| user_access_level | 总是 | 执行作业的用户访问级别。在极狐GitLab 16.9 中引入。 |
| user_identities | 用户首选项设置 | 用户的外部身份列表(在极狐GitLab 16.0 中引入)。 |
| pipeline_id | 总是 | 流水线的 ID。 |
| pipeline_source | 总是 | 流水线来源。 |
| job_id | 总是 | 作业的 ID。 |
| ref | 总是 | 作业的 Git 引用。 |
| ref_type | 总是 | Git 引用类型,可以是 branch 或 tag。 |
| ref_path | 总是 | 作业的完全限定引用。例如,refs/heads/main。在极狐GitLab 16.0 中引入。 |
| ref_protected | 总是 | 如果 Git 引用受保护为 true,否则为 false。 |
| groups_direct | 用户直接属于 0 到 200 个群组 | 用户直接所属群组的路径。如果用户直接属于超过 200 个群组,则省略。(在极狐GitLab 16.11 中引入,并在极狐GitLab 17.3 中放置在 ci_jwt_groups_direct 功能标志 后面。 |
| environment | 作业指定环境 | 此作业部署到的环境。 |
| environment_protected | 作业指定环境 | 如果部署环境受保护为 true,否则为 false。 |
| deployment_tier | 作业指定环境 | 作业指定的环境的 部署层级。(在极狐GitLab 15.2 中引入)。 |
| environment_action | 作业指定环境 | 作业中指定的 环境操作 (environment:action)。(在极狐GitLab 16.5 中引入)。 |
| runner_id | 总是 | 执行作业的 runner 的 ID。在极狐GitLab 16.0 中引入。 |
| runner_environment | 总是 | 作业使用的 runner 类型。可以是 gitlab-hosted 或 self-hosted。在极狐GitLab 16.0 中引入。 |
| sha | 总是 | 作业的提交 SHA。在极狐GitLab 16.0 中引入。 |
| ci_config_ref_uri | 总是 | 顶级流水线定义的引用路径,例如,gitlab.example.com/my-group/my-project//.gitlab-ci.yml@refs/heads/main。在极狐GitLab 16.2 中引入。除非流水线定义位于同一项目中,否则此声明为 null。 |
| ci_config_sha | 总是 | ci_config_ref_uri 的 Git 提交 SHA。在极狐GitLab 16.2 中引入。除非流水线定义位于同一项目中,否则此声明为 null。 |
| project_visibility | 总是 | 流水线运行所在项目的 可见性。可以是 internal、private 或 public。在极狐GitLab 16.3 中引入。 |
json1{ 2 "namespace_id": "72", 3 "namespace_path": "my-group", 4 "project_id": "20", 5 "project_path": "my-group/my-project", 6 "user_id": "1", 7 "user_login": "sample-user", 8 "user_email": "sample-user@example.com", 9 "user_identities": [ 10 {"provider": "github", "extern_uid": "2435223452345"}, 11 {"provider": "bitbucket", "extern_uid": "john.smith"} 12 ], 13 "pipeline_id": "574", 14 "pipeline_source": "push", 15 "job_id": "302", 16 "ref": "feature-branch-1", 17 "ref_type": "branch", 18 "ref_path": "refs/heads/feature-branch-1", 19 "ref_protected": "false", 20 "groups_direct": ["mygroup/mysubgroup", "myothergroup/myothersubgroup"], 21 "environment": "test-environment2", 22 "environment_protected": "false", 23 "deployment_tier": "testing", 24 "environment_action": "start", 25 "runner_id": 1, 26 "runner_environment": "self-hosted", 27 "sha": "714a629c0b401fdce83e847fc9589983fc6f46bc", 28 "project_visibility": "public", 29 "ci_config_ref_uri": "gitlab.example.com/my-group/my-project//.gitlab-ci.yml@refs/heads/main", 30 "ci_config_sha": "714a629c0b401fdce83e847fc9589983fc6f46bc", 31 "jti": "235b3a54-b797-45c7-ae9a-f72d7bc6ef5b", 32 "iss": "https://gitlab.example.com", 33 "iat": 1681395193, 34 "nbf": 1681395188, 35 "exp": 1681398793, 36 "sub": "project_path:my-group/my-project:ref_type:branch:ref:feature-branch-1", 37 "aud": "https://vault.example.com" 38}
ID 令牌使用 RS256 编码并使用专用私钥签名。令牌的过期时间设置为作业的超时时间(如果指定),或 5 分钟(如果未指定超时)。
使用第三方服务进行 ID 令牌身份验证
您可以使用 ID 令牌与第三方服务进行 OIDC 身份验证。例如:
疑难解答
400: missing token 状态码
此错误表示一个或多个 ID 令牌必要的基本组件丢失或未按预期配置。
要找到问题,管理员可以在实例的 exceptions_json.log 中查找失败的特定方法的详细信息。
GitLab::Ci::Jwt::NoSigningKeyError
此错误在 exceptions_json.log 文件中可能是因为签名密钥丢失在数据库中,令牌无法生成。要验证这是问题,请在实例的 PostgreSQL 终端上运行以下查询:
sqlSELECT encrypted_ci_jwt_signing_key FROM application_settings;
如果返回值为空,请使用下面的 Rails 代码片段生成新密钥并在内部替换:
rubykey = OpenSSL::PKey::RSA.new(2048).to_pem ApplicationSetting.find_each do |application_setting| application_setting.update(ci_jwt_signing_key: key) end