教程:更新 HashiCorp Vault 配置以使用 ID 令牌

本教程演示如何转换现有的 CI/CD secret 配置以使用 ID 令牌

CI_JOB_JWT 变量已废弃,但更新到 ID 令牌需要进行一些重要的配置更改才能与 Vault 配合使用。如果您有多个作业,一次性转换所有内容是一项艰巨的任务。

从 15.9 到 15.11,启用自动 ID 令牌身份验证设置以启用 ID 令牌并禁用 CI_JOB_JWT 令牌。

在 16.0 及更高版本中,您可以使用 ID 令牌,而无需更改任何设置。 自动使用 secrets:vault 的作业没有可用的 CI_JOB_JWT 令牌, 不使用 secrets:vault 的作业仍然可以使用 CI_JOB_JWT 令牌。

本教程将重点介绍 v16 及以上版本,如果您运行的是稍旧的版本,则需要根据需要切换 Limit JSON Web Token (JWT) access 设置。

要更新您的 vault 配置以使用 ID 令牌:

  1. 在 Vault 中创建第二个 JWT 身份验证路径
  2. 重新创建角色以使用新的身份验证路径
  3. 更新您的 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。

在 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 令牌。

  1. 配置名为 jwt_v2 的新身份验证路径,运行:

    vault auth enable -path jwt_v2 jwt
    

    您可以选择不同的名称,但这些示例的其余部分假设您使用 jwt_v2,因此请根据需要更新示例。

  2. 为您的实例配置新的身份验证路径:

    $ vault write auth/jwt_v2/config \
        jwks_url="https://gitlab.example.com/-/jwks" \
        bound_issuer="https://gitlab.example.com"
    

重新创建角色以使用新的身份验证路径

角色绑定到特定的身份验证路径,因此您需要为每个作业添加新角色。

  1. 重新创建名为 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
    
  2. 重新创建名为 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

更新您的 CI/CD 作业

Vault 有两个不同的 KV Secrets Engine,您使用的版本会影响您在 CI/CD 中定义 secret 的方式。

HashiCorp 支持门户上的检查我的 Vault KV Mount 是哪个版本可以检查您的 Vault 服务器。

此外,如果需要,您可以查看 CI/CD 文档:

以下示例显示如何获取写入到 secret/myproject/staging/dbpassword 字段的临时数据库密码。

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_URLVAULT_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。