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

CI/CDジョブトークン

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

CI/CDパイプラインジョブの実行が近づくと、GitLabは一意のトークンを生成し、CI_JOB_TOKEN定義済み変数としてジョブで利用できるようにします。このトークンは、ジョブの実行中にのみ有効です。ジョブが完了すると、トークンアクセスは失効し、このトークンは使用できなくなります。

CI/CDジョブトークンを使用して、実行中のジョブから特定のGitLab機能に対して認証を行います。トークンは、パイプラインをトリガーしたユーザーと同じアクセスレベルを付与されますが、アクセスできるリソースはパーソナルアクセストークンよりも少なくなります。ユーザーは、コミットをプッシュするか、手動ジョブを実行するか、またはスケジュールされたパイプラインのオーナーであることによって、ジョブをトリガーすることができます。このユーザーには、リソースにアクセスするために必要な権限を持つロールが付与されている必要があります。

ジョブトークンを使用してGitLabに対して認証し、別のグループやプロジェクトのリソース(ターゲットプロジェクト)にアクセスできます。デフォルトでは、ジョブトークンのグループまたはプロジェクトは、ターゲットプロジェクトの許可リストに追加する必要があります。

プロジェクトが公開または内部の場合、許可リストに登録されていなくても、一部の機能にはアクセスできます。たとえば、プロジェクトの公開パイプラインからアーティファクトをフェッチできます。このようなアクセスを制限することもできます。

ジョブトークンアクセス

CI/CDジョブトークンは、次のリソースにアクセスできます。

リソース備考
Badges APIこのAPIのすべてのエンドポイントにアクセスできます。
ブランチAPIGET /projects/:id/repository/branchesエンドポイントにアクセスできます。
コミットAPIGET /projects/:id/repository/commits/:shaおよびGET /projects/:id/repository/commits/:sha/merge_requestsエンドポイントにアクセスできます。
コンテナレジストリジョブのプロジェクトに関連付けられたコンテナレジストリに対して認証するために、$CI_REGISTRY_PASSWORD定義済み変数として使用します。
パッケージレジストリレジストリに対する認証に使用します。
Terraformモジュールレジストリレジストリに対する認証に使用します。
セキュアファイルglab securefileコマンドによって、ジョブでセキュアファイルを使用します。
コンテナレジストリAPIジョブのプロジェクトに関連付けられたコンテナレジストリに対してのみ認証できます。
デプロイAPIこのAPIのすべてのエンドポイントにアクセスできます。
環境APIこのAPIのすべてのエンドポイントにアクセスできます。
ファイルAPIGET /projects/:id/repository/files/:file_path/rawエンドポイントにアクセスできます。
ジョブAPIGET /jobエンドポイントのみにアクセスできます。
ジョブアーティファクトAPIダウンロードエンドポイントのみアクセスできます。
マージリクエストAPIGET /projects/:id/merge_requestsおよびGET /projects/:id/merge_requests/:merge_request_iidエンドポイントにアクセスできます。
ノートAPIGET /projects/:id/merge_requests/:merge_request_iid/notesおよびGET /projects/:id/merge_requests/:merge_request_iid/notes/:note_idエンドポイントにアクセスできます。
パッケージAPIこのAPIのすべてのエンドポイントにアクセスできます。
パイプライントリガートークンAPIPOST /projects/:id/trigger/pipelineエンドポイントのみにアクセスできます。
パイプラインAPIPUT /projects/:id/pipelines/:pipeline_id/metadataエンドポイントのみにアクセスできます。
リリースリンクAPIこのAPIのすべてのエンドポイントにアクセスできます。
リリースAPIこのAPIのすべてのエンドポイントにアクセスできます。
リポジトリAPI公開リポジトリのGET /projects/:id/repository/changelogエンドポイントのみアクセスできます。
タグAPIGET /projects/:id/repository/tagsおよびGET /projects/:id/repository/tags/:tag_nameエンドポイントにアクセスできます。

権限をより細かく制御できるようにするための公開提案が存在します。

GitLab CI/CDジョブトークンのセキュリティ

CI/CDジョブトークンが漏洩した場合、CI/CDジョブを実行したユーザーがアクセスできるプライベートデータにアクセスするために使用される可能性があります。このようなトークンの漏洩や不正利用を防ぐために、GitLabは以下を行います。

  • ジョブログでジョブトークンをマスクする。
  • ジョブの実行中にのみジョブトークンに権限を付与する。

さらに、Runnerを設定する際には、セキュリティを確保するために次の点に注意してください。

  • マシンが再利用される場合は、Dockerのprivilegedモードを使用しない。
  • 複数のジョブが同じマシンで実行される場合は、shell executorを使用しない。

脆弱なGitLab Runner設定は、他のジョブからトークンを盗まれるリスクを増大させます。

プロジェクトへのジョブトークンアクセスを制御する

どのグループまたはプロジェクトがジョブトークンで認証し、プロジェクトのリソースの一部にアクセスできるかを制御できます。

デフォルトでは、ジョブトークンでのアクセスは、そのユーザーのプロジェクト内のパイプラインで実行されるCI/CDジョブのみに制限されています。別のグループまたはプロジェクトが、他のプロジェクトのパイプラインからのジョブトークンで認証できるようにするには、次の条件を満たす必要があります。

プロジェクトが公開または内部の場合、公開アクセスが許可されている一部のリソースには、任意のプロジェクトのジョブトークンでアクセスできます。このようなリソースを、許可リストに追加されたプロジェクトのみに制限することもできます。

GitLab Self-Managedの管理者は、この設定をオーバーライドして適用できます。この設定が適用されると、CI/CDジョブトークンは常にプロジェクトの許可リストに制限されます。

ジョブトークン許可リストにグループまたはプロジェクトを追加する

ジョブトークン許可リストにグループまたはプロジェクトを追加すると、ジョブトークンによる認証を通じてプロジェクトのリソースへのアクセスを許可できます。デフォルトでは、プロジェクトの許可リストにはそのプロジェクト自体のみが含まれています。クロスプロジェクトアクセスが必要な場合にのみ、グループまたはプロジェクトを許可リストに追加します。

許可リストにプロジェクトを追加しても、許可リストに登録されたプロジェクトのメンバーに追加の権限が付与されるわけではありません。許可リストに登録されたプロジェクトのジョブトークンを使用してプロジェクトにアクセスするには、プロジェクト内のリソースにアクセスする権限がそのユーザーにすでに付与されている必要があります。

たとえば、プロジェクトAの許可リストにプロジェクトBを追加するとします。これにより、プロジェクトB(「許可されたプロジェクト」)のCI/CDジョブは、CI/CDジョブトークンを使用してAPIコールを認証し、プロジェクトAにアクセスできるようになります。

前提条件:

  • 現在のプロジェクトでメンテナーまたはオーナーロールが必要です。許可されたプロジェクトが内部またはプライベートの場合、そのプロジェクトでゲスト、プランナー、レポーター、デベロッパー、メンテナー、またはオーナーロールが必要です。
  • 許可リストに追加できるグループとプロジェクトの数は最大で200です。

グループまたはプロジェクトを許可リストに追加するには、次のようにします。

  1. 上部のバーで、検索または移動先を選択して、プロジェクトを見つけます。
  2. 左サイドバーで、設定 > CI/CDを選択します。
  3. ジョブトークンの権限を展開します。
  4. CI/CDジョブトークン許可リストの右側にある追加を選択します。
  5. グループまたはプロジェクトを選択します。
  6. 許可リストに追加するグループまたはプロジェクトへのパスを入力して、追加をクリックします。

APIを使用してグループまたはプロジェクトを許可リストに追加することもできます。

公開プロジェクトまたは内部プロジェクトのジョブトークンのスコープを制限する

許可リストに含まれていないプロジェクトでも、ジョブトークンを使用して公開または内部プロジェクトに対して認証し、次の操作を行えます。

  • アーティファクトのフェッチ。
  • コンテナレジストリへのアクセス。
  • パッケージレジストリへのアクセス。
  • リリース、デプロイ、環境へのアクセス。
  • リポジトリにアクセスします。

各機能をプロジェクトメンバーのみに表示されるよう設定することで、これらのアクションへのアクセスを、許可リストに含まれるプロジェクトのみに制限できます。

前提条件:

  • プロジェクトのメンテナーロールを持っている必要があります。

機能をプロジェクトメンバーのみが表示できるように設定するには、次のようにします。

  1. 上部のバーで、検索または移動先を選択して、プロジェクトを見つけます。
  2. 左側のサイドバーで、設定 > 一般を選択します。
  3. 可視性、プロジェクトの機能、権限を展開します。
  4. アクセスを制限する機能の表示レベルをプロジェクトメンバーのみに設定します。
    • アーティファクトをフェッチする機能は、CI/CDの表示レベルの設定によって制御されます。
  5. 変更を保存を選択します。

すべてのプロジェクトから自分のプロジェクトへのアクセスを許可する

  • 提供形態: GitLab Self-Managed、GitLab Dedicated

トークンアクセス制限と許可リストを無効にすると、セキュリティリスクになります。悪意のあるユーザーが、許可されていないプロジェクトで作成済みのパイプラインを侵害しようとする可能性があります。パイプラインがいずれかのメンテナーによって作成された場合、プロジェクトへのアクセスを試みるためにジョブトークンが悪用される可能性があります。

CI/CDジョブトークン許可リストを無効にすると、どのプロジェクトのジョブからでも、ジョブトークンを使用してプロジェクトにアクセスできるようになります。パイプラインをトリガーするユーザーには、プロジェクトにアクセスする権限が必要です。この設定を無効にするのはテストや同様の目的に限定し、可能な限り速やかに再度有効にする必要があります。

このオプションを利用できるのは、全プロジェクトでジョブトークン許可リストを有効にして適用する設定が無効になっているGitLab Self-ManagedまたはGitLab Dedicatedインスタンスのみです。

前提条件:

  • プロジェクトのメンテナーまたはオーナーロールが必要です。

ジョブトークン許可リストを無効にするには、次のようにします。

  1. 上部のバーで、検索または移動先を選択して、プロジェクトを見つけます。
  2. 左サイドバーで、設定 > CI/CDを選択します。
  3. ジョブトークンの権限を展開します。
  4. 全グループとプロジェクトを選択します。
  5. 推奨。テストが完了したら、このプロジェクトと許可リスト内のグループとプロジェクトのみを選択して、ジョブトークン許可リストを再度有効にします。

この設定は、GraphQLinboundJobTokenScopeEnabled)またはREST APIでも変更できます。

プロジェクトリポジトリへのGitプッシュリクエストを許可する

CI/CDジョブトークンで認証するGitプッシュリクエストを許可するようにプロジェクトを設定できます。この設定はデフォルトでオフになっています。

この設定をオンにすると、プロジェクトのパイプラインで実行されるCI/CDジョブによって生成されたCI/CDジョブトークンのみを、プロジェクトにプッシュできます。

CI/CDジョブトークンを使用してプロジェクトにプッシュする場合、CI/CDパイプラインはトリガーされることはありません。CI/CDジョブトークンには、ジョブを開始したユーザーと同じアクセス権限があります。

semantic-releaseツールを使用する場合、この設定によりパイプラインの作成が妨げられる可能性があります。

プルミラーとして設定されたプロジェクトでは、この設定を有効にしないでください。ミラーの更新のためにパイプラインが実行される場合は特にそうです。アップストリームリポジトリのオーナーは、CI_JOB_TOKENを使用してコミットをミラーされたプロジェクトにプッシュする可能性があります。

前提条件:

  • プロジェクトのメンテナーまたはオーナーロールが必要です。

プロジェクトで生成されたジョブトークンにプロジェクトのリポジトリにプッシュする権限を付与するには、次のようにします。

  1. 上部のバーで、検索または移動先を選択して、プロジェクトを見つけます。
  2. 左サイドバーで、設定 > CI/CDを選択します。
  3. ジョブトークンの権限を展開します。
  4. 権限セクションで、リポジトリへのGitプッシュリクエストを許可するを選択します。

設定は、projects APIci_push_repository_for_job_token_allowedパラメータでも制御できます。

許可リストにあるプロジェクトからの、プロジェクトをまたぐGitプッシュリクエストを許可する

許可リストにあるプロジェクトからのCI/CDジョブトークンが、プロジェクトのリポジトリにプッシュすることを許可できます。これは、GitOpsワークフロー、サブモジュールのタグ付け、および長期間有効なアクセストークンを使用しないクロスプロジェクトCI/CDパイプラインに役立ちます。

CI/CDジョブトークンのプッシュが成功した場合、ターゲットプロジェクトでCI/CDパイプラインはトリガーされることはありません。

プルミラーとして設定されたプロジェクトでは、この設定を有効にしないでください。パイプラインがミラーの更新のためにトリガーされる場合は特にそうです。許可リストにあるソースプロジェクトのオーナーが、CI/CDジョブトークンを使用して、コミットをミラーされたプロジェクトにプッシュする可能性があります。

クロスプロジェクトプッシュが機能するためには、次のすべてが真である必要があります:

  • ターゲットプロジェクトでリポジトリへのGitプッシュリクエストを許可するが有効になっていること。
  • ターゲットプロジェクトで許可リストにあるプロジェクトからの、プロジェクトをまたぐGitプッシュリクエストを許可するが有効になっていること。
  • ターゲットプロジェクトでCI/CDジョブトークン許可リストが有効になっていること。
  • ソースプロジェクトがadmin_repositories 詳細な権限を持つターゲットプロジェクトの許可リストにあるか、またはデフォルトの権限(詳細な制限が設定されていない)を持っていること。ソースプロジェクトを含む許可リスト上のグループエントリも、この要件を満たします。
  • パイプラインを開始したユーザーが、ターゲットプロジェクトで少なくともデベロッパーロールを持っていること。

前提条件:

  • プロジェクトのメンテナーまたはオーナーロールが必要です。

クロスプロジェクトプッシュリクエストを許可するには:

  1. 上部のバーで、検索または移動先を選択して、プロジェクトを見つけます。
  2. 設定 > CI/CDを選択します。
  3. ジョブトークンの権限を展開します。
  4. 権限セクションで、リポジトリへのGitプッシュリクエストを許可するを選択します。
  5. 許可リストにあるプロジェクトからの、プロジェクトをまたぐGitプッシュリクエストを許可するを選択します。
  6. 変更を保存を選択します。
  7. ソースプロジェクトまたはそのグループを許可リストに追加するときは、ADMIN_REPOSITORIES詳細な権限を付与するか、デフォルトの権限を有効のままにしてください。

ジョブトークンの詳細なアクセス許可設定

詳細な権限を使用して、限られたREST APIエンドポイントへのアクセスを明示的に許可できます。

詳細については、CI/CDジョブトークンの詳細なアクセス許可設定を参照してください。

Gitリポジトリのクローン

ジョブトークンを使用すると、CI/CDジョブで認証を行い、非公開プロジェクトからリポジトリのクローンを作成できます。gitlab-ci-tokenをユーザーとして使用し、ジョブトークンの値をパスワードとして使用します。

例:

git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.example.com/<namespace>/<project>

HTTPSプロトコルがグループ、プロジェクト、またはインスタンスの設定によって無効になっている場合でも、このジョブトークンを使用してリポジトリのクローンを作成できます。

REST API認証

CI/CDジョブトークンを使用して、次の方法で特定のREST APIエンドポイントに対するリクエストを認証することができます:

  • ヘッダー: --header "JOB-TOKEN: $CI_JOB_TOKEN" (推奨)
  • フォーム: --form "token=$CI_JOB_TOKEN"
  • データ: --data "job_token=$CI_JOB_TOKEN"
  • URL内のクエリ文字列: ?job_token=$CI_JOB_TOKEN (非推奨)

例えば、推奨されるヘッダー方式を使用する場合:

curl --verbose --request POST --header "JOB-TOKEN: $CI_JOB_TOKEN" --form ref=master "https://gitlab.com/api/v4/projects/1234/trigger/pipeline"

トークンのセキュリティに関するガイダンスについては、セキュリティに関する考慮事項を参照してください。

CI/CDジョブトークンを使用してGraphQLリクエストを認証することはできません。

ジョブトークン認証ログ

他のどのプロジェクトがCI/CDジョブトークンを使用して自分のプロジェクトに対して認証しているかは、認証ログで追跡できます。ログを確認するには、以下を実行します。

  1. 上部のバーで、検索または移動先を選択して、プロジェクトを見つけます。
  2. 左サイドバーで、設定 > CI/CDを選択します。
  3. ジョブトークンの権限を展開します。認証ログセクションには、ジョブトークンで認証してプロジェクトにアクセスした他のプロジェクトのリストが表示されます。
  4. オプション。認証ログ全体をCSV形式でダウンロードするには、CSVをダウンロードをクリックします。

認証ログには、最大100件の認証イベントが表示されます。イベント数が100件を超える場合は、CSVファイルをダウンロードしてログを確認してください。

プロジェクトへの新しい認証が認証ログに表示されるまで、最長5分かかる場合があります。

CI/CDトークンのレガシー形式を使用する

GitLab 19.0以降、CI/CDジョブトークンはデフォルトでJWT(JSON Webトークン)標準を使用しています。プロジェクトのトップレベルグループを設定すると、プロジェクトでレガシー形式を引き続き使用できます。この設定が利用できるのは、GitLab 20.0リリースまでです。

CI/CDトークンのレガシー形式を使用するには、次のようにします。

  1. 上部のバーで、検索または移動先を選択して、グループを見つけます。
  2. 左サイドバーで、設定 > CI/CDを選択します。
  3. 一般パイプラインを展開します。
  4. CI/CDジョブトークンのJWTフォーマットを有効にするをオフにします。

これにより、CI/CDトークンがレガシー形式を使用するようになります。後ほどJWT形式を再び使用する場合は、この設定を再度有効にします。

トラブルシューティング

CIジョブトークンの失敗は以下のとおり、通常、404 Not Foundなどの応答として表示されます。

  • 許可されていないGitクローン:

    $ git clone https://gitlab-ci-token:$CI_JOB_TOKEN@gitlab.com/fabiopitino/test2.git
    
    Cloning into 'test2'...
    remote: The project you were looking for could not be found or you don't have permission to view it.
    fatal: repository 'https://gitlab-ci-token:[MASKED]@gitlab.com/<namespace>/<project>.git/' not found
  • 許可されていないパッケージのダウンロード:

    $ wget --header="JOB-TOKEN: $CI_JOB_TOKEN" ${CI_API_V4_URL}/projects/1234/packages/generic/my_package/0.0.1/file.txt
    
    --2021-09-23 11:00:13--  https://gitlab.com/api/v4/projects/1234/packages/generic/my_package/0.0.1/file.txt
    Resolving gitlab.com (gitlab.com)... 172.65.251.78, 2606:4700:90:0:f22e:fbec:5bed:a9b9
    Connecting to gitlab.com (gitlab.com)|172.65.251.78|:443... connected.
    HTTP request sent, awaiting response... 404 Not Found
    2021-09-23 11:00:13 ERROR 404: Not Found.
  • 許可されていないAPIリクエスト:

    $ curl --verbose --request POST --form "token=$CI_JOB_TOKEN" --form ref=master "https://gitlab.com/api/v4/projects/1234/trigger/pipeline"
    
    < HTTP/2 404
    < date: Thu, 23 Sep 2021 11:00:12 GMT
    {"message":"404 Not Found"}
    < content-type: application/json

CI/CDジョブトークン認証の問題を解決する際は、以下の点に注意する必要があります。

  • プロジェクトごとにスコープ設定を切り替えるには、GraphQLミューテーションサンプルを利用できます。
  • このコメントは、BashとcURLでGraphQLを使用して、以下を行う方法を説明しています。
    • 受信トークンのアクセススコープを有効にする。
    • プロジェクトAからプロジェクトBへのアクセス権を付与する、またはBをAの許可リストに追加する。
    • プロジェクトのアクセス権を削除する。
  • ジョブがもはや実行されていない場合、消去された場合、またはプロジェクトが削除処理中の場合、CIジョブトークンは無効になります。

semantic-releaseツールとCI/CDジョブトークン

リポジトリへのGitプッシュリクエストを許可する設定semantic-releaseツールを使用する場合、既知のイシューがあります。有効にすると:

  • ツールがパーソナルアクセストークンを使用するように設定されていても、ツールはCI/CDジョブトークンで認証する。
  • CI/CDジョブトークンは新しいパイプラインをトリガーしないため、リリースパイプラインが実行されない可能性があります。

詳細については、イシュー891を参照してください。

JWT形式のジョブトークンのエラー

CI/CDジョブトークンのJWT形式には、既知の問題がいくつかあります。

EC2 Fargate RunnerカスタムexecutorのError when persisting the task ARN.エラー

EC2 Fargateカスタムexecutorの0.5.0以前のバージョンにはバグがあります。この問題により、以下のエラーが発生します。

  • Error when persisting the task ARN. Will stop the task for cleanup

この問題を修正するには、Fargateカスタムexecutorのバージョン0.5.1以降にアップグレードしてください。

base64エンコードのinvalid character '\n' in string literalエラー

base64を使用してジョブトークンをエンコードすると、invalid character '\n'エラーが発生する場合があります。

これは、base64コマンドのデフォルトの動作では、79文字を超える文字列は折り返されるためです。ジョブ実行中に、たとえばecho $CI_JOB_TOKEN | base64を使用してJWT形式のジョブトークンをbase64でエンコードすると、そのトークンは無効になります。

この問題を修正するには、base64 -w0を使用してトークンの自動折り返しを無効にします。

エラー: 実行時間の長いジョブでの403 Forbidden

GitLab 18.8以前でJWT形式のCI/CDジョブトークンを使用すると、ジョブが403 Forbiddenエラーで失敗する可能性があります。これは次の状況で発生する可能性があります:

  • needsを使用するジョブ。
  • 子パイプライン内のジョブ。
  • コンソール出力を生成せずに約6分以上実行されるジョブ。

エラーは通常、Runnerログに次のように表示されます:

WARNING: Submitting job to coordinator... job failed
  code=403 job=<job_id> status=PUT https://gitlab.com/api/v4/jobs/<job_id>: 403 Forbidden

このイシューを回避するには、GitLab 18.9にアップデートしてください。