チュートリアル: IDトークンを使用するようにHashiCorp Vault設定を更新する
- プラン: Premium、Ultimate
- 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated
Vault 1.17以降、JWTにaudクレームが含まれている場合、JWT認証ログインにはロールにbound_audiencesの設定が必要です。audクレームには、単一の文字列または文字列のリストを指定できます。
このチュートリアルでは、既存のCI/CDシークレット設定をID Tokensを使用するように変換する方法を説明します。
CI_JOB_JWT変数は非推奨ですが、IDトークンに更新するには、Vaultと連携するための重要な設定変更が必要です。ジョブが少数にとどまらない場合、すべてを一度に変換するのは困難なタスクです。
IDトークンに移行するための標準的な方法は1つではありません。そのため、このチュートリアルでは、既存のCI/CDシークレットを変換する2つのバリエーションを紹介します。お客様のユースケースに最適な方法を選択してください:
- Vaultの設定を更新します:
- 方法A: JWTロールを新しいVault認証方式に移行します
- 方法B: 移行ウィンドウのロールに
issクレームを移動します
- CI/CDのジョブを更新する
前提要件
このチュートリアルでは、GitLab CI/CDとVaultについて理解していることを前提としています。
次に進むには、以下が必要です:
- GitLab 16.0以降を実行しているインスタンス、またはGitLab.com上に存在すること。
- 既に使用しているVaultサーバー。
CI_JOB_JWTを使用して、Vaultからシークレットを取得するCI/CDジョブ。
以下の例では、以下を置き換えてください:
vault.example.comに、あなたのVaultサーバーのURLを指定します。gitlab.example.comをGitLabインスタンスのURLに置き換えます。jwtまたはjwt_v2を認証方式の名前に置き換えます。
方法A: JWTロールを新しいVault認証方式に移行します
この方法では、使用中の既存のものと並行して、2番目のJWT認証方式を作成します。その後、GitLabインテグレーションに使用されるすべてのVaultロールは、この新しい認証方式で再作成されます。
Vaultに2つ目のJWT認証パスを作成します
CI_JOB_JWTからIDトークンへの移行の一環として、Vaultのbound_issuerを更新してhttps://を含める必要があります:
$ vault write auth/jwt/config \
oidc_discovery_url="https://gitlab.example.com" \
bound_issuer="https://gitlab.example.com"この変更を行うと、CI_JOB_JWTを使用するジョブは失敗し始めます。
Vaultに複数の認証パスを作成できます。これにより、中断することなく、ジョブベースでプロジェクトのIDトークンに移行できます。
名前
jwt_v2の新しい認証パスを設定するには、以下を実行します:vault auth enable -path jwt_v2 jwt別の名前を選択できますが、これらの例の残りの部分では
jwt_v2を使用していることを前提としているため、必要に応じて例を更新してください。インスタンスの新しい認証パスを設定します:
$ vault write auth/jwt_v2/config \ oidc_discovery_url="https://gitlab.example.com" \ bound_issuer="https://gitlab.example.com"
新しい認証パスを使用するようにロールを再作成します
ロールは特定の認証パスにバインドされているため、各ジョブに新しいロールを追加する必要があります。JWTにオーディエンスが含まれている場合、ロールのbound_audiencesパラメータは必須であり、関連付けられているaudクレームの少なくとも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_audiences": ["https://vault.example.com"], "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_audiences": ["https://vault.example.com"], "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管理者が2番目のJWT認証方式を作成し、GitLabに関連するすべてのロールを再作成する必要はありません。
各ロールにbound_issuersクレームマップを追加します
Vaultでは、JWT認証方式レベルで複数のissクレームは許可されていません。このレベルのbound_issuerディレクティブは、単一の値のみを受け入れるためです。ただし、bound_claimsマップ設定ディレクティブを使用すると、ロールレベルで複数のクレームを設定できます。
この方法を使用すると、Vaultにissクレーム検証の複数のオプションを提供できます。これにより、https://のプレフィックスが付いたGitLabインスタンスホスト名クレームがサポートされます。これは、古いプレフィックスなしのクレームと同様に、id_tokensに付属しています。
必要なロールに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"
}
}
EOFbound_claimsセクションを除き、既存のロール設定を変更する必要はありません。前に示したようにiss設定を追加して、Vaultがこのロールのプレフィックス付きおよびプレフィックスなしのissクレームを受け入れるようにしてください。
次のステップに進む前に、GitLabインテグレーションに使用されるすべてのJWTロールにこの変更を適用する必要があります。
すべてのプロジェクトが移行され、CI_JOB_JWTとIDトークンの並列サポートが不要になった場合は、必要に応じて、issクレーム検証の移行を認証方法からロールにレビューできます。
認証方式からbound_issuersクレームを削除します
すべてのロールがbound_claims.issクレームで更新されたら、この検証の認証方式レベルの設定を削除できます:
$ vault write auth/jwt/config \
oidc_discovery_url="https://gitlab.example.com" \
bound_issuer=""bound_issuerディレクティブを空の文字列に設定すると、認証方式レベルで発行者検証が削除されます。ただし、この検証はロールレベルで行われるようになったため、設定は依然として安全です。
CI/CDジョブを更新します
Vaultには2つの異なるKVシークレットエンジンがあり、使用しているバージョンはCI/CDでシークレットを定義する方法に影響します。
Vaultサーバーを確認するには、HashiCorpのサポートポータルにあるどのバージョンが自分のVault KVマウントか?という記事を確認してください。
また、必要に応じて、CI/CDドキュメントで以下をレビューできます:
次の例は、secret/myproject/staging/dbのpasswordフィールドに書き込まれたステージングデータベースのパスワードを取得する方法を示しています。
VAULT_AUTH_PATH変数の値は、使用した移行方法によって異なります:
- 方法A (Vault認証の新しいJWTロールへの移行方法):
jwt_v2を使用してください。 - 方法B (
issクレームを移行ウィンドウのロールに移動する):jwtを使用してください。
KVシークレットエンジンv1
secrets:vaultキーワードはKVマウントのv2にデフォルト設定されているため、v1エンジンを使用するようにジョブを明示的に設定する必要があります:
job:
variables:
VAULT_SERVER_URL: https://vault.example.com
VAULT_AUTH_PATH: jwt_v2 # or "jwt" if you used method B
VAULT_AUTH_ROLE: myproject-staging
id_tokens:
VAULT_ID_TOKEN:
aud: https://vault.example.com
secrets:
PASSWORD:
vault:
engine:
name: kv-v1
path: secret
field: password
path: myproject/staging/db
file: falseVAULT_SERVER_URLとVAULT_AUTH_PATHの両方を、必要に応じてプロジェクトまたはグループのCI/CD変数として定義できます。
secrets:fileはfalseに設定されています。これは、IDトークンがシークレットをデフォルトでファイルに配置し、古い動作と一致するように、通常の変数として動作する必要があるためです。
KVシークレットエンジンv2
v2エンジンに使用できる形式は2つあります。
長い形式:
job:
variables:
VAULT_SERVER_URL: https://vault.example.com
VAULT_AUTH_PATH: jwt_v2 # or "jwt" if you used method B
VAULT_AUTH_ROLE: myproject-staging
id_tokens:
VAULT_ID_TOKEN:
aud: https://vault.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 # or "jwt" if you used method B
VAULT_AUTH_ROLE: myproject-staging
id_tokens:
VAULT_ID_TOKEN:
aud: https://vault.example.com
secrets:
PASSWORD:
vault: myproject/staging/db/password@secret
file: false更新されたCI/CD設定をコミットすると、ジョブはIDトークンでシークレットをフェッチします。おめでとうございます。
すべてのプロジェクトを移行してIDトークンでシークレットをフェッチし、移行に方法Bを使用した場合は、必要に応じて、issクレーム検証を認証方法の設定に戻すことができます。