在 CI 中使用外部 secret
密钥代表了需要完成您 CI 作业的敏感信息。这些敏感信息可能是 API 令牌、数据库凭据或私钥。密钥存储在您的密钥提供器中。
和 CI/CD 变量不一样,密钥必须由作业明确要求。关于语法的更对详情,可阅读极狐GitLab CI/CD 流水线配置参考以获取更多信息。
极狐GitLab 支持一下密钥管理提供商:
极狐GitLab 已经选择 Hashicorp Valut 作为第一个支持提供商,KV-V2是第一个支持的密钥引擎。
使用 ID 令牌来使用 ID 令牌进行身份验证。使用 Hashicorp Vault 进行身份验证和读取机密教程中有关使用 ID 令牌进行身份验证的更多详细信息。
在您可以在 CI 作业中使用 Vault 密钥之前,您必须配置您的 Vault 服务器。
以下是极狐GitLab 和 Vault 集成的示意图:
- 配置您的 vault 和密钥。
- 生成您的 JWT 并将其提供给您的 CI 作业。
- Runner 联系 HashiCorp Vault 并使用 JWT 进行身份验证。
- HashiCorp Vault 验证 JWT。
- HashiCorp Vault 检查绑定的声明并附加策略。
- HashiCorp Vault 返回令牌。
- Runner 从 HashiCorp Vault 中读取密钥。
您必须将下面的 vault.example.com
URL 替换为您的 Vault 服务器,并将 gitlab.example.com
替换为您的极狐GitLab 实例 URL。
Vault 密钥引擎
generic
选项引入于极狐GitLab Runner 16.11。
极狐GitLab Runner 支持的 Vault 密钥引擎有:
密钥引擎 |
secrets:engine:name 值 |
Runner 版本 | 详情 |
---|---|---|---|
KV secrets engine - version 2 | kv-v2 |
13.4 | 当没有显式指定引擎类型时,极狐GitLab 默认使用 kv-v2 。 |
KV secrets engine - version 1 |
kv-v1 或 generic
|
13.4 | 对于 generic 关键字的支持引入于极狐GitLab 15.11。 |
The AWS secrets engine | generic |
16.11 | |
Hashicorp Vault Artifactory Secrets Plugin | generic |
16.11 | 此密钥后端和 JFrog Artifactory server (5.0.0 及以后) 进行通信并动态创建具有特定范围的访问令牌。 |
配置您的 Vault 服务器
要配置您的 Vault 服务器:
- 确保您的 Vault 服务器在 1.2.0 或更高版本上运行。
-
通过运行这些命令启用身份验证方法。他们为您的实例提供 JSON Web 密钥集 (JWKS) 端点,以便认证时, Vault 可以获取公共签名密钥并验证 JSON Web 令牌 (JWT) :
$ vault auth enable jwt $ vault write auth/jwt/config \ jwks_url="https://gitlab.example.com/-/jwks" \ bound_issuer="gitlab.example.com"
-
在您的 Vault 服务器上配置策略,授予或禁止对某些路径和操作的访问。此示例授予对生产环境所需的一组 secret 的读取访问权限:
vault policy write myproject-production - <<EOF # Read-only permission on 'ops/data/production/*' path path "ops/data/production/*" { capabilities = [ "read" ] } EOF
- 在您的 Vault 服务器上配置角色,将角色限制为项目或命名空间,如本页 配置 Vault 服务器角色 中所述。
- 创建以下 CI/CD 变量,提供有关您的 Vault 服务器的详细信息:
-
VAULT_SERVER_URL
- Vault 服务器的 URL,例如https://vault.example.com:8200
。必需。 -
VAULT_AUTH_ROLE
-(可选)尝试进行身份验证时使用的角色。如果未指定角色,Vault 将使用配置身份验证方法时指定的默认角色。 -
VAULT_AUTH_PATH
-(可选)挂载认证方法的路径,默认为jwt
。 -
VAULT_NAMESPACE
- 可选。 Vault 企业命名空间用来读取密钥和进行验证。使用:- Vault,当没有指定命名空间时使用
root
(“/
”) 命名空间。 - Vault Open source,忽略该设置。
-
HashiCorp Cloud Platform (HCP) Vault,需要一个命名空间。默认情况下 HCP Vault 使用
admin
命名空间作为 root 命名空间。比如,VAULT_NAMESPACE=admin
。
- Vault,当没有指定命名空间时使用
-
在 CI 作业中使用 Vault secret
配置您的 Vault 服务器后,您可以通过使用 vault
关键字,定义存储在 Vault 中的 secret,然后使用它们:
job_using_vault:
id_tokens:
VAULT_ID_TOKEN:
aud: https://vault.example.com
secrets:
DATABASE_PASSWORD:
vault: production/db/password@ops # translates to secret `ops/data/production/db`, field `password`
token: $VAULT_ID_TOKEN
在这个例子中:
-
production/db
- secret。 -
password
- 字段。 -
ops
- 安装 secret engine 的路径。
极狐GitLab 从 Vault 获取 secret 后,该值将保存在一个临时文件中。此文件的路径存储在名为 DATABASE_PASSWORD
的 CI/CD 变量中。
要覆盖默认,请显式设置 file
选项:
secrets:
id_tokens:
VAULT_ID_TOKEN:
aud: https://vault.example.com
DATABASE_PASSWORD:
vault: production/db/password@ops
file: false
token: $VAULT_ID_TOKEN
在这个例子中,secret 值直接放在 DATABASE_PASSWORD
变量中,而不是指向保存它的文件。
使用不同的密钥引擎
默认情况下使用 kv-v2
密钥引擎。要使用其他引擎,请在配置中将 engine
部分添加到 vault
下。
比如,要为 Artifactory 设置密钥引擎和路径:
job_using_vault:
id_tokens:
VAULT_ID_TOKEN:
aud: https://vault.example.com
secrets:
JFROG_TOKEN:
vault:
engine:
name: generic
path: artifactory
path: production/jfrog
field: access_token
file: false
在此示例中,secret 值从 artifactory/production/jfrog
获取,字段为 access_token
。generic
密钥引擎可用于 kv-v1
、AWS、Artifactory 和其他类似 vault 密钥引擎。
配置 Vault 服务器角色
当 CI 作业尝试进行身份验证时,它会指定一个角色。您可以使用角色将不同的策略组合在一起。如果身份验证成功,这些策略将附加到生成的 Vault 令牌。
绑定声明 是与 JWT 声明匹配的预定义值。使用 bounded claims,您可以为特定 Git 引用,限制对特定极狐GitLab 用户、特定项目甚至运行的作业的访问。您可以拥有所需数量的 bounded claims,但它们必须全部匹配才能成功进行身份验证。
将 bounded claims 与用户角色和受保护分支等功能相结合,您可以定制这些规则来适合您的特定用例。在此示例中,仅允许为受保护标签运行的作业进行身份验证,其名称与用于生产版本的 pattern 相匹配:
$ vault write auth/jwt/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": "42",
"ref_protected": "true",
"ref_type": "tag",
"ref": "auto-deploy-*"
}
}
EOF
project_id
或 namespace_id
)将您的角色限制在项目或命名空间。在没有这些限制的情况下,可以允许此实例生成的任何 JWT 使用此角色进行身份验证。您还可以为生成的 Vault 令牌指定一些属性,例如生存时间、IP 地址范围和使用次数。JSON 网络令牌方法的完整选项列表可在 Vault 的创建角色文档 中找到。
使用自签名的 Vault 服务器
当 Vault 服务器使用自签名证书时,您可以在作业日志中看到如下错误:
ERROR: Job failed (system failure): resolving secrets: initializing Vault service: preparing authenticated client: checking Vault server health: Get https://vault.example.com:8000/v1/sys/health?drsecondarycode=299&performancestandbycode=299&sealedcode=299&standbycode=299&uninitcode=299: x509: certificate signed by unknown authority
您有两种方法来解决此错误:
- 将自签名证书添加到极狐GitLab Runner 服务器的 CA sotre 中。如果您使用的是Helm chart部署的 runner,您需要创建您自己的极狐GitLab Runner 镜像。
- 使用
VAULT_CACERT
环境变量来配置极狐GitLab Runner 以信任证书:- If you are using systemd to manage GitLab Runner, see how to add an environment variable for GitLab Runner.
- 如果您正在使用 systemd 来管理极狐GitLab Runner,请参阅如何为极狐GitLab Runner 添加环境变量。
- 如果您使用的是Helm chart部署的极狐GitLab Runner:
-
提供一个能访问极狐GitLab 的自定义证书,并确保添加 Vault 服务器的证书而不是极狐GitLab 的证书。如果您的极狐GitLab 实例也使用自签名证书,您可以将两个证书添加到同一个
Secret
中。 -
在您的
values.yaml
文件中添加以下行:## Replace both the <SECRET_NAME> and the <VAULT_CERTIFICATE> ## with the actual values you used to create the secret certsSecretName: <SECRET_NAME> envVars: - name: VAULT_CACERT value: "/home/gitlab-runner/.gitlab-runner/certs/<VAULT_CERTIFICATE>"
-
提供一个能访问极狐GitLab 的自定义证书,并确保添加 Vault 服务器的证书而不是极狐GitLab 的证书。如果您的极狐GitLab 实例也使用自签名证书,您可以将两个证书添加到同一个
故障排查
resolving secrets: secret not found: MY_SECRET
错误
当极狐GitLab 在 vault 中无法找到密钥时,就会报如下错误:
ERROR: Job failed (system failure): resolving secrets: secret not found: MY_SECRET
检查以确保 vault
的值在 CI/CD 作业中配置正确。
您可以使用 kv
命令与 Vault CLI来检查是否可以从 vault 中检索到密钥,以帮助确定 CI/CD 配置中 vault
值的语法。例如,要检索密钥:
$ vault kv get -field=password -namespace=admin -mount=ops "production/db"
this-is-a-password