教程:更新 HashiCorp Vault 配置以使用 ID 令牌
本教程演示如何转换现有的 CI/CD secret 配置以使用 ID 令牌。
CI_JOB_JWT
变量已废弃,但更新到 ID 令牌需要进行一些重要的配置更改才能与 Vault 配合使用。如果您有多个作业,一次性转换所有内容是一项艰巨的任务。
迁移到 ID 令牌并没有一个标准方法,因此本教程包括两种将现有 CI/CD secret 转换的方法。选择最适合您用例的方法:
- 更新您的 Vault 配置:
- 方法 A:迁移 JWT 角色到新的 Vault auth 方法
- 方法 B:为迁移窗口,移动
iss
声明到角色
- 更新您的 CI/CD 作业
先决条件
本教程假设您熟悉极狐GitLab CI/CD 和 Vault。
要继续操作,您必须具备:
- 运行极狐GitLab 15.9 或更高版本的实例,或者位于 JihuLab.com 上。
- 您已经在使用的 Vault 服务器。
- CI/CD 作业使用
CI_JOB_JWT
从 Vault 检索 secret。
在下面的示例中,替换:
-
vault.example.com
为您的 Vault 服务器 URL。 -
gitlab.example.com
为您的极狐GitLab 实例 URL。 -
jwt
orjwt_v2
为您的 auth 方法名称。
方法 A: 迁移 JWT 角色到新的 Vault auth 方法
此方法会创建一个与现有方法并行的第二个 JWT 身份验证路径。然后,重新创建用于极狐GitLab 集成的所有 Vault 角色。
在 Vault 中创建第二个 JWT 身份验证路径
作为从 CI_JOB_JWT
过渡到 ID 令牌的一部分,您必须更新 Vault 中的 bound_issuer
以包含 https://
:
$ vault write auth/jwt/config \
jwks_url="https://gitlab.example.com/-/jwks" \
bound_issuer="https://gitlab.example.com"
进行此更改后,使用 CI_JOB_JWT
的作业开始失败。
您可以在 Vault 中创建多个身份验证路径,使您能够在不中断的情况下按作业基础过渡到项目上的 IT 令牌。
-
配置名为
jwt_v2
的新身份验证路径,运行:vault auth enable -path jwt_v2 jwt
您可以选择不同的名称,但这些示例的其余部分假设您使用
jwt_v2
,因此请根据需要更新示例。 -
为您的实例配置新的身份验证路径:
$ vault write auth/jwt_v2/config \ jwks_url="https://gitlab.example.com/-/jwks" \ bound_issuer="https://gitlab.example.com"
重新创建角色以使用新的身份验证路径
角色绑定到特定的身份验证路径,因此您需要为每个作业添加新角色。
-
重新创建名为
myproject-staging
的暂存角色:$ vault write auth/jwt_v2/role/myproject-staging - <<EOF { "role_type": "jwt", "policies": ["myproject-staging"], "token_explicit_max_ttl": 60, "user_claim": "user_email", "bound_claims": { "project_id": "22", "ref": "master", "ref_type": "branch" } } EOF
-
重新创建名为
myproject-production
的生产角色:$ vault write auth/jwt_v2/role/myproject-production - <<EOF { "role_type": "jwt", "policies": ["myproject-production"], "token_explicit_max_ttl": 60, "user_claim": "user_email", "bound_claims_type": "glob", "bound_claims": { "project_id": "22", "ref_protected": "true", "ref_type": "branch", "ref": "auto-deploy-*" } } EOF
您只需在 vault
命令中将 jwt
更新为 jwt_v2
,不要更改角色内部的 role_type
。
方法 B:为迁移窗口,移动 iss
声明到角色
此方法不会要求 Vault 管理员创建第二个 JWT 身份验证方法并重新创建所有极狐GitLab 相关角色。
添加 bound_issuers
声明以匹配每个角色
Vault 不允许在 JWT 身份验证方法级别上设置多个 iss
声明,因为 bound_issuer
在此级别上仅接受单个值。但是,可以使用 bound_claims
在角色级别上配置多个声明。
使用此方法,您可以为 Vault 提供多个 iss
声明的选项。这支持 id_tokens
中随附的以 https://
为前缀的极狐GitLab 实例主机名声明,以及旧的非前缀声明。
要添加 bound_claims
配置到所需的每个角色,请运行:
$ vault write auth/jwt/role/myproject-staging - <<EOF
{
"role_type": "jwt",
"policies": ["myproject-staging"],
"token_explicit_max_ttl": 60,
"user_claim": "user_email",
"bound_audiences": ["https://vault.example.com"],
"bound_claims": {
"iss": [
"https://gitlab.example.com",
"gitlab.example.com"
],
"project_id": "22",
"ref": "master",
"ref_type": "branch"
}
}
EOF
您无需更改现有角色配置,除了 bound_claims
部分。请确保添加上面显示的 iss
配置,以确保 Vault 接受此角色的前缀和非前缀 iss
声明。
在继续下一步之前,将此更改应用于所有用于极狐GitLab 集成的 JWT 角色。
您可以在所有项目迁移完成后,如果不再需要对 CI_JOB_JWT
和 ID 令牌的并行支持,可以选择将 iss
声明验证的迁移从认证方法恢复到角色。
从 auth 方法移除 bound_issuers
声明
在用 bound_claims.iss
声明更新所有角色后,您可以为此验证移除 auth 方法级别的配置:
$ vault write auth/jwt/config \
oidc_discovery_url="https://gitlab.example.com" \
bound_issuer=""
直接将 bound_issuer
设置为空字符串会删除 auth 方法级别的验证。但是,由于我们已将此验证移动到角色级别,因此此配置仍然安全。
更新您的 CI/CD 作业
Vault 有两个不同的 KV Secrets Engine,您使用的版本会影响您在 CI/CD 中定义 secret 的方式。
HashiCorp 支持门户上的检查我的 Vault KV Mount 是哪个版本可以检查您的 Vault 服务器。
此外,如果需要,您可以查看 CI/CD 文档:
以下示例显示如何获取写入到 secret/myproject/staging/db
中 password
字段的临时数据库密码。
The following examples show how to obtain the staging database password written to the password
field in secret/myproject/staging/db
.
VAULT_AUTH_PATH
变量的值取决于您所使用的迁移方法:
- 方法 A(迁移 JWT 角色到新的 Vault auth 方法):使用
jwt_v2
。 - 方法 B(为迁移窗口,移动
iss
声明到橘色):使用jwt
。
KV Secrets Engine v1
secrets:vault
关键字默认为 KV Mount 的 v2,因此您需要显式配置作业以使用 v1 引擎:
job:
variables:
VAULT_SERVER_URL: https://vault.example.com
VAULT_AUTH_PATH: jwt_v2
VAULT_AUTH_ROLE: myproject-staging
id_tokens:
VAULT_ID_TOKEN:
aud: https://gitlab.example.com
secrets:
PASSWORD:
vault:
engine:
name: kv-v1
path: secret
field: password
path: myproject/staging/db
file: false
VAULT_SERVER_URL
和 VAULT_AUTH_PATH
都可以定义为项目或群组 CI/CD 变量。
我们使用 secrets:file:false
,因为 ID 令牌默认将 secret 放置在文件中,但我们需要它以常规变量的方式匹配旧的行为。
KV Secrets Engine v2
v2 引擎可以使用两种格式。
长格式:
job:
variables:
VAULT_SERVER_URL: https://vault.example.com
VAULT_AUTH_PATH: jwt_v2
VAULT_AUTH_ROLE: myproject-staging
id_tokens:
VAULT_ID_TOKEN:
aud: https://gitlab.example.com
secrets:
PASSWORD:
vault:
engine:
name: kv-v2
path: secret
field: password
path: myproject/staging/db
file: false
这与 v1 引擎的示例相同,但 secrets:vault:engine:name:
设置为 kv-v2
以匹配引擎。
您还可以使用短格式:
job:
variables:
VAULT_SERVER_URL: https://vault.example.com
VAULT_AUTH_PATH: jwt_v2
VAULT_AUTH_ROLE: myproject-staging
id_tokens:
VAULT_ID_TOKEN:
aud: https://gitlab.example.com
secrets:
PASSWORD:
vault: myproject/staging/db/password@secret
file: false
提交更新的 CI/CD 配置后,您的作业将使用 ID 令牌获取 secret。
如果您已经将所有项目迁移到使用 ID 令牌获取 secret,并且使用方法 B 进行迁移,则现在可以将 iss
声明验证移回 auth 方法配置(如果需要)。