GitLab CI/CD でジョブ単位に OIDC ID トークン(JWT) を発行する .gitlab-ci.yml のキーワード。GCP の Workload Identity Federation や AWS の AssumeRoleWithWebIdentity、HashiCorp Vault などの外部認証先に対して、 静的キーなしで自分の身元を主張する ための仕組み。
基本構文
deploy_gcp:
id_tokens:
GCP_ID_TOKEN:
aud: https://iam.googleapis.com/projects/<num>/locations/global/workloadIdentityPools/<pool>/providers/<provider>
script:
- echo "$GCP_ID_TOKEN" > /tmp/oidc.jwt
- # 以降、JWT を使ってクラウド STS と credential 交換
ジョブ内で 任意の名前の環境変数 として ID トークンが配られる。aud(audience claim)は受け取り側のシステムに合わせて設定する。
旧仕様との関係(CI_JOB_JWT / CI_JOB_JWT_V2)
id_tokens キーワードが導入される以前は、 CI_JOB_JWT / CI_JOB_JWT_V2 という事前定義変数で同様のトークンが配られていた。
| 観点 | 旧仕様(CI_JOB_JWT_V2) | 新仕様(id_tokens) |
|---|---|---|
| 配布範囲 | 全ジョブに自動配布 | 明示宣言したジョブのみ |
| audience | GitLab インスタンス URL に固定 | ジョブ単位で複数指定可能 |
| 変数展開 | 不可 | GitLab 16.1+ で aud に変数展開可 |
| 状態 | GitLab 15.9(2023-02)で非推奨、17.0 で削除予定 | 現行推奨 |
CI_JOB_JWT_V2 は事前定義変数だったため、 不要なジョブにもトークンが渡る 、 複数の信頼境界(GCP・AWS・Vault)を 1 ジョブで使い分けにくい といった制約があった。id_tokens ではこれらが解消されている。
主な使い分け(aud の代表例)
| 連携先 | aud の値 |
|---|---|
| GCP WIF | https://iam.googleapis.com/projects/<num>/locations/global/workloadIdentityPools/<pool>/providers/<provider> |
| AWS OIDC IdP | https://gitlab.com(または GitLab セルフホスト URL) |
| HashiCorp Vault | https://vault.example.com 等の Vault エンドポイント |
| Sigstore | sigstore |
複数の連携先を 1 ジョブで使う場合は、 別名のトークンを並列で宣言 する(公式仕様)。
multi_target:
id_tokens:
GCP_TOKEN: { aud: https://iam.googleapis.com/... }
AWS_TOKEN: { aud: https://gitlab.com }
VAULT_TOKEN:{ aud: https://vault.example.com }
移行時の典型的な落とし穴
- WIF Provider 側の
allowed_audiencesを変更せずにaudだけ書き換えるとInvalid token audienceで失敗する CI_JOB_JWT_V2を参照したまま放置していると、 GitLab 17.0 アップグレード時にパイプライン全停止 のリスク- セルフホスト GitLab で
audを SaaS 値(https://gitlab.com)にしているとそもそも検証が通らない
関連記事・用語
- GitLab → GCP 認証方式の 3 世代と CTS の選択 —
CI_JOB_JWT_V2からid_tokensへの移行を含む遍歴 - WIF でキーレス認証 —
id_tokensを使った WIF 連携の実装 - Workload Identity Federation —
id_tokensの主要連携先 - Service Account Impersonation —
id_tokensの JWT を使って SA を借りる仕組み - OpenID Connect — JWT の発行プロトコル