正式なドキュメントは英語版であり、この日本語訳はAI支援翻訳により作成された参考用のものです。日本語訳の一部の内容は人間によるレビューがまだ行われていないため、翻訳のタイミングにより英語版との間に差異が生じることがあります。最新かつ正確な情報については、英語版をご参照ください。

IDトークンを使用したOpenID Connect(OIDC)認証

  • プラン: Free、Premium、Ultimate
  • 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated

IDトークンは、JSON Webトークン (JSON Webトークン)で、GitLab CI/CDによって生成されます。CI/CDジョブは、サードパーティサービスとのOIDC認証にIDトークンを使用できます。対象となるサービスは次のとおりです:

たとえば、IDトークンを使用してHashiCorp Vaultで認証を行うフローは、次の図にまとめられています:

sequenceDiagram
    participant GitLab as GitLab CI/CD
    participant Runner as GitLab Runner
    participant Vault as HashiCorp Vault

    GitLab->>Runner: Generates an ID token (JWT) for the CI/CD job

    Runner->>Vault: Runner authenticates with HashiCorp Vault using the token

    Vault->>Vault: HashiCorp Vault verifies the token

    Vault->>Vault: HashiCorp Vault checks bounded claims and attaches policies

    Vault->>Runner: HashiCorp Vault returns the token

    Runner->>Vault: Runner requests secrets from HashiCorp Vault
    Vault->>Runner: Returns secrets

IDトークンは、secretsキーワードでも使用されます。

CI/CDジョブでIDトークンを設定する

IDトークンを使用するには、id_tokensキーワードでCI/CDジョブを設定します。

例:

job_with_id_tokens:
  id_tokens:
    FIRST_ID_TOKEN:
      aud: https://first.service.com
    SECOND_ID_TOKEN:
      aud: https://second.service.com
  script:
    - first-service-authentication-script.sh $FIRST_ID_TOKEN
    - second-service-authentication-script.sh $SECOND_ID_TOKEN

この例では、2つのトークンには異なるaudクレームが含まれています。サードパーティサービスは、バインドされたオーディエンスに一致するaudクレームを持たないトークンを拒否するように設定できます。この機能を使用して、トークンが認証に使用できるサービスの数を減らします。これにより、トークンが侵害された場合の重大度が軽減されます。

トークンのペイロード

各IDトークンには、次の標準クレームが含まれています:

フィールド説明
issトークンの発行者。これはGitLabインスタンスのドメイン(「issuer」クレーム)です。
subトークンのサブジェクト(「subject」クレーム)。デフォルトはproject_path:{group}/{project}:ref_type:{type}:ref:{branch_name}です。プロジェクトAPIでプロジェクトに対して設定できます。
audトークンの対象オーディエンス(「audience」クレーム)。IDトークン設定で指定されます。デフォルトではGitLabインスタンスのドメイン。
exp有効期限(「expiration time」クレーム)。
nbfトークンが有効になる時刻(「not before」クレーム)。
iatJWTが発行された時刻(「issued at」クレーム)。
jtiトークンの固有識別子(「JWT ID」クレーム)。

トークンには、GitLabによって提供されるカスタムクレームも含まれています:

フィールド使用時説明
project_id常時ジョブを実行しているプロジェクトのID。マージリクエストパイプラインでは、これはソースブランチプロジェクトのIDです。
project_path常時ジョブを実行しているプロジェクトのパス。マージリクエストパイプラインでは、これはソースブランチプロジェクトのパスです。
namespace_id常時ジョブを実行しているプロジェクトのネームスペースID。マージリクエストパイプラインでは、これはソースブランチプロジェクトのネームスペースIDです。
namespace_path常時ジョブを実行しているプロジェクトのネームスペースパス。マージリクエストパイプラインでは、これはソースブランチプロジェクトのネームスペースパスです。
user_id常時ジョブを実行しているユーザーのID。
user_login常時ジョブを実行しているユーザーのユーザー名。
user_email常時ジョブを実行しているユーザーのメール。
user_access_level常時ジョブを実行しているユーザーのアクセスレベル。GitLab 16.9で導入されました。
job_project_id常時ジョブを実行しているプロジェクトのID。これを使用して、IDでプロジェクトにスコープを設定します。GitLab 18.4で導入されました。
job_project_path常時ジョブを実行しているプロジェクトのパス。これを使用して、パスでプロジェクトにスコープを設定します。GitLab 18.4で導入されました。
job_namespace_id常時ジョブを実行しているプロジェクトのネームスペースID。IDでグループまたはユーザーレベルのネームスペースにスコープを設定するために使用します。GitLab 18.4で導入されました。
job_namespace_path常時ジョブを実行しているプロジェクトのネームスペースパス。パスでグループまたはユーザーレベルのネームスペースにスコープを設定するために使用します。GitLab 18.4で導入されました。
user_identitiesユーザー設定で有効のときユーザーの外部IDのリスト(GitLab 16.0で導入されました)。
pipeline_id常時パイプラインのID。
pipeline_source常時パイプラインソース
job_id常時ジョブのID。
ref常時このジョブのGit ref。マージリクエストパイプラインでは、これはソースブランチrefsです。
ref_type常時Git refタイプ(branchまたはtag)。
ref_path常時ジョブの完全修飾参照。たとえばrefs/heads/mainなどです。マージリクエストパイプラインでは、これはソースブランチrefsパスです。GitLab 16.0で導入されました。
ref_protected常時Git参照が保護されている場合はtrue、それ以外の場合はfalse
groups_directユーザーが0 - 200のグループの直接メンバーであるときユーザーの直接メンバーシップグループのパス。ユーザーが200を超えるグループの直接のメンバーである場合は省略されます。(GitLab 16.11で導入され、GitLab 17.3でci_jwt_groups_direct機能フラグの背後に置かれました。
environmentジョブが環境を指定するときこのジョブのデプロイ先の環境。
environment_protectedジョブが環境を指定するときデプロイされた環境が保護されている場合はtrue、それ以外の場合はfalse
deployment_tierジョブが環境を指定するときジョブが指定する環境のデプロイ層。GitLab 15.2で導入されました。
environment_actionジョブが環境を指定するときジョブで指定された環境アクション(environment:action。(GitLab 16.5で導入されました)
runner_id常時ジョブを実行しているRunnerのID。GitLab 16.0で導入されました。
runner_environment常時ジョブで使用されるRunnerのタイプ。gitlab-hostedまたはself-hostedのいずれかになります。GitLab 16.0で導入されました。
sha常時ジョブのコミットSHA。GitLab 16.0で導入されました。
ci_config_ref_uri常時トップレベルのパイプライン定義への参照パス(例: gitlab.example.com/my-group/my-project//.gitlab-ci.yml@refs/heads/main)。GitLab 16.2で導入されました。パイプライン定義が同じプロジェクトにない場合、このクレームはnullです。
ci_config_sha常時ci_config_ref_uriのGitコミットSHA。GitLab 16.2で導入されました。パイプライン定義が同じプロジェクトにない場合、このクレームはnullです。
project_visibility常時パイプラインが実行されているプロジェクトの表示レベルinternalprivate、またはpublicを指定できます。GitLab 16.3で導入されました。
{
  "namespace_id": "72",
  "namespace_path": "my-group",
  "project_id": "20",
  "project_path": "my-group/my-project",
  "user_id": "1",
  "user_login": "sample-user",
  "user_email": "sample-user@example.com",
  "user_identities": [
      {"provider": "github", "extern_uid": "2435223452345"},
      {"provider": "bitbucket", "extern_uid": "john.smith"}
  ],
  "pipeline_id": "574",
  "pipeline_source": "push",
  "job_id": "302",
  "ref": "feature-branch-1",
  "ref_type": "branch",
  "ref_path": "refs/heads/feature-branch-1",
  "ref_protected": "false",
  "groups_direct": ["mygroup/mysubgroup", "myothergroup/myothersubgroup"],
  "environment": "test-environment2",
  "environment_protected": "false",
  "deployment_tier": "testing",
  "environment_action": "start",
  "runner_id": 1,
  "runner_environment": "self-hosted",
  "sha": "714a629c0b401fdce83e847fc9589983fc6f46bc",
  "project_visibility": "public",
  "ci_config_ref_uri": "gitlab.example.com/my-group/my-project//.gitlab-ci.yml@refs/heads/main",
  "ci_config_sha": "714a629c0b401fdce83e847fc9589983fc6f46bc",
  "jti": "235b3a54-b797-45c7-ae9a-f72d7bc6ef5b",
  "iss": "https://gitlab.example.com",
  "iat": 1681395193,
  "nbf": 1681395188,
  "exp": 1681398793,
  "sub": "project_path:my-group/my-project:ref_type:branch:ref:feature-branch-1",
  "aud": "https://vault.example.com"
}

IDトークンはRS256を使用してエンコードされ、専用の秘密キーで署名されます。トークンの有効期限は、ジョブのタイムアウト(指定されている場合)または5分(タイムアウトが指定されていない場合)に設定されます。

トラブルシューティング

400: missing tokenステータスコード

このエラーは、IDトークンに必要な基本コンポーネントが1つ以上欠落しているか、予期したとおりに設定されていないことを示しています。

管理者が問題を特定するには、失敗した特定の方法について、インスタンスのexceptions_json.logで詳細を確認できます。

GitLab::Ci::Jwt::NoSigningKeyError

exceptions_json.logファイル内のこのエラーは、署名キーがデータベースから欠落しており、トークンを生成できなかったことが原因で発生している可能性があります。これが問題であることを確認するには、インスタンスのPostgreSQLターミナルで次のクエリを実行します:

SELECT encrypted_ci_jwt_signing_key FROM application_settings;

返された値が空の場合は、次のRailsスニペットを使用して新しいキーを生成し、内部的に置き換えます:

  key = OpenSSL::PKey::RSA.new(2048).to_pem

  ApplicationSetting.find_each do |application_setting|
    application_setting.update(ci_jwt_signing_key: key)
  end

401: unauthorizedステータスコード

このエラーは、認証リクエストが失敗したことを示しています。GitLabパイプラインから外部サービスへのOpenID Connect(OIDC)認証を使用する場合、次のようないくつかの一般的な理由により401 Unauthorizedエラーが発生することがあります:

  • $CI_JOB_JWT_V2のような非推奨のトークンを、IDトークンの代わりに使ってしまった。詳細については、古いバージョンのJSON Webトークンは非推奨を参照してください。
  • .gitlab-ci.ymlファイルと外部サービスのOIDC Identity Providerの設定の間でprovider_nameの値が一致していない。
  • GitLabが発行したIDトークンと、外部サービスが予期する内容の間で、aud(オーディエンス)クレームが欠落しているか、一致していない。
  • GitLab CI/CDジョブでid_tokens:ブロックを有効にしていないか、設定していない。

このエラーを解決するには、ジョブ内でトークンをデコードします:

echo $OIDC_TOKEN | cut -d '.' -f2 | base64 -d | jq .

以下を確認してください:

  • aud(オーディエンス)が、予期されるオーディエンス(外部サービスのURLなど)と一致している。
  • sub(サブジェクト)が、サービスのIdentity Providerの設定でマップされている。
  • preferred_usernameが、デフォルトでGitLab IDトークンに存在しない。