チュートリアルIDトークンを使用するためのHashiCorp Vault設定の更新
このチュートリアルでは、既存のCI/CDシークレット設定をIDトークンを使用するように変更する方法を説明します。
CI_JOB_JWT 変数は非推奨ですが、ID トークンに更新するには、Vault で動作するようにいくつかの重要な設定を変更する必要があります。ジョブが一握り以上ある場合、すべてを一度に変換するのは大変な作業です。
GitLab 15.9から15.11では、IDトークンの自動認証設定を有効にしてIDトークンを有効にし、CI_JOB_JWT トークンを無効にしてください。
GitLab 16.0以降では、設定を変更することなくIDトークンを使用できます。secrets:vault を自動的に使用するジョブはCI_JOB_JWT トークンを使用できません。secrets:vault を使用しないジョブはCI_JOB_JWT トークンを使用できます。
このチュートリアルではv16以降に焦点をあてて説明します。少し古いバージョンを使用している場合は、Limit JSON Web Token (JWT) access の設定を適切に切り替える必要があります。
IDトークンにマイグレーションするための標準的な方法は1つではないので、このチュートリアルには既存のCI/CDシークレットを変換する方法の2つのバリエーションが含まれています。あなたのユースケースに最も適した方法を選択してください:
- Vaultの設定を更新します:
- 方法A:JWTロールを新しいVault認証メソッドにマイグレーションします。
- 方法B:
issクレームをマイグレーションウィンドウのロールに移動します。
- CI/CDジョブの更新
前提条件
このチュートリアルでは、GitLab CI/CDとVaultに精通していることを前提としています。
このチュートリアルに従うには、以下のものが必要です:
- GitLab 15.9以降が稼働しているインスタンス、またはGitLab.comを利用していること。
- 既に使用しているVaultサーバー。
- CI/CD ジョブは、
CI_JOB_JWTを使って Vault からシークレットを取得します。
以下の例では
-
vault.example.comをVaultサーバのURLに置き換えてください。 -
gitlab.example.comには GitLab インスタンスの URL を指定します。 -
jwtまたはjwt_v2に認証メソッド名を指定します。
方法A:JWTロールを新しいVault認証メソッドにマイグレーションします。
この方法では、既存のJWT認証メソッドと並行して2つ目のJWT認証メソッドを作成します。その後、GitLabインテグレーションに使用されているすべてのVaultロールが、この新しい認証メソッドに再作成されます。
Vaultに2つ目の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管理者が2つ目のJWT認証メソッドを作成したり、GitLab関連のロールをすべて作り直したりする必要はありません。
bound_issuers claim map を各ロールに追加します。
このレベルのbound_issuer ディレクティブは単一の値しか受け付けないため、Vault は JWT 認証メソッドレベルで複数のiss クレームを許可しません。しかし、bound_claims map設定ディレクティブを使うことで、ロールレベルで複数のクレームを設定することができます。
この方法を使えば、iss クレーム検証のための複数のオプションを Vault に提供することができます。これは、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_claims": {
"iss": [
"https://gitlab.example.com",
"gitlab.example.com"
],
"project_id": "22",
"ref": "master",
"ref_type": "branch"
}
}
EOF
bound_claims セクションを除き、既存のロール設定を変更する必要はありません。iss Vaultが issこのロールのiss プレフィックス付きおよびプレフィックスなしの issクレームをiss 受け付けるように、上記のように設定を iss追加してください。
次のステップに進む前に、GitLabインテグレーションで使用するすべてのJWTロールにこの変更を適用する必要があります。
すべてのプロジェクトがマイグレーションされ、CI_JOB_JWT と ID トークンの並行サポートが不要になった後で、必要であればiss のクレーム検証を認証メソッドからロールにマイグレーションを戻すことができます。
auth メソッドからbound_issuers クレームを削除します。
すべてのロールがbound_claims.iss 、この検証のための認証メソッドレベルの設定を削除することができます:
$ vault write auth/jwt/config \
jwks_url="https://gitlab.example.com/-/jwks" \
bound_issuer=""
bound_issuer ディレクティブを空文字列に設定することで、認証メソッドレベルでの発行者検証が削除されます。ディレクティブを空文字列に設定することで、auth メソッドレベルでの発行者検証が削除されます。しかし、この検証をロールレベルに移したので、この設定はまだ安全です。
CI/CDジョブの更新
Vaultには2つの異なるKVシークレットエンジンがあり、使用しているバージョンはCI/CDでシークレットを定義する方法に影響します。
HashiCorpのサポートポータルにあるVault KV Mountのバージョンは?の記事で、お使いのVaultサーバを確認してください。
また、必要に応じて、CI/CDのドキュメントをレビューすることができます:
以下の例は、secret/myproject/staging/db のpassword フィールドに書き込まれたステージングデータベースのパスワードを取得する方法を示しています。
VAULT_AUTH_PATH 変数の値は、使用したマイグレーション方法によって異なります:
- 方法A(JWTロールを新しいVault認証方法にマイグレーション):
jwt_v2を使用します。 - 方法B(
issクレームをマイグレーションウィンドウのロールに移行):jwtを使用してください。
KVシークレットエンジンv1
secrets:vault キーワードのデフォルトは KV Mount の 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://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トークンがデフォルトでファイルにシークレットを置くからですが、古い動作と一致させるために通常の変数として動作させる必要があります。
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://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 # or "jwt" if you used method B
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トークンでシークレットを取得するようになります!
すべてのプロジェクトを ID トークンでシークレットを取得するようにマイグレーションし、マイグレーションにメソッド B を使用した場合、iss のクレーム検証を auth メソッド設定に戻すことができます。