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のすべてのエンドポイントにアクセスできます。 |
| ブランチAPI | GET /projects/:id/repository/branchesエンドポイントにアクセスできます。 |
| コミットAPI | GET /projects/:id/repository/commits/:shaおよびGET /projects/:id/repository/commits/:sha/merge_requestsエンドポイントにアクセスできます。 |
| コンテナレジストリ | ジョブのプロジェクトに関連付けられたコンテナレジストリに対して認証するために、$CI_REGISTRY_PASSWORD定義済み変数として使用します。 |
| パッケージレジストリ | レジストリに対する認証に使用します。 |
| Terraformモジュールレジストリ | レジストリに対する認証に使用します。 |
| セキュアファイル | glab securefileコマンドによって、ジョブでセキュアファイルを使用します。 |
| コンテナレジストリAPI | ジョブのプロジェクトに関連付けられたコンテナレジストリに対してのみ認証できます。 |
| デプロイAPI | このAPIのすべてのエンドポイントにアクセスできます。 |
| 環境API | このAPIのすべてのエンドポイントにアクセスできます。 |
| ファイルAPI | GET /projects/:id/repository/files/:file_path/rawエンドポイントにアクセスできます。 |
| ジョブAPI | GET /jobエンドポイントのみにアクセスできます。 |
| ジョブアーティファクトAPI | ダウンロードエンドポイントのみアクセスできます。 |
| マージリクエストAPI | GET /projects/:id/merge_requestsおよびGET /projects/:id/merge_requests/:merge_request_iidエンドポイントにアクセスできます。 |
| ノートAPI | GET /projects/:id/merge_requests/:merge_request_iid/notesおよびGET /projects/:id/merge_requests/:merge_request_iid/notes/:note_idエンドポイントにアクセスできます。 |
| パッケージAPI | このAPIのすべてのエンドポイントにアクセスできます。 |
| パイプライントリガートークンAPI | POST /projects/:id/trigger/pipelineエンドポイントのみにアクセスできます。 |
| パイプラインAPI | PUT /projects/:id/pipelines/:pipeline_id/metadataエンドポイントのみにアクセスできます。 |
| リリースリンクAPI | このAPIのすべてのエンドポイントにアクセスできます。 |
| リリースAPI | このAPIのすべてのエンドポイントにアクセスできます。 |
| リポジトリAPI | 公開リポジトリのGET /projects/:id/repository/changelogエンドポイントのみアクセスできます。 |
| タグAPI | GET /projects/:id/repository/tagsおよびGET /projects/:id/repository/tags/:tag_nameエンドポイントにアクセスできます。 |
権限をより細かく制御できるようにするための公開提案が存在します。
GitLab CI/CDジョブトークンのセキュリティ
CI/CDジョブトークンが漏洩した場合、CI/CDジョブを実行したユーザーがアクセスできるプライベートデータにアクセスするために使用される可能性があります。このようなトークンの漏洩や不正利用を防ぐために、GitLabは以下を行います。
- ジョブログでジョブトークンをマスクする。
- ジョブの実行中にのみジョブトークンに権限を付与する。
さらに、Runnerを設定する際には、セキュリティを確保するために次の点に注意してください。
- マシンが再利用される場合は、Dockerの
privilegedモードを使用しない。 - 複数のジョブが同じマシンで実行される場合は、
shellexecutorを使用しない。
脆弱なGitLab Runner設定は、他のジョブからトークンを盗まれるリスクを増大させます。
プロジェクトへのジョブトークンアクセスを制御する
どのグループまたはプロジェクトがジョブトークンで認証し、プロジェクトのリソースの一部にアクセスできるかを制御できます。
デフォルトでは、ジョブトークンでのアクセスは、そのユーザーのプロジェクト内のパイプラインで実行されるCI/CDジョブのみに制限されています。別のグループまたはプロジェクトが、他のプロジェクトのパイプラインからのジョブトークンで認証できるようにするには、次の条件を満たす必要があります。
- ジョブトークンの許可リストにグループまたはプロジェクトを追加する必要があります。
- ジョブをトリガーするユーザーが、アクセス対象のプロジェクトのメンバーである必要があります。
- ユーザーには、アクションを実行するための権限が付与されている必要があります。
プロジェクトが公開または内部の場合、公開アクセスが許可されている一部のリソースには、任意のプロジェクトのジョブトークンでアクセスできます。このようなリソースを、許可リストに追加されたプロジェクトのみに制限することもできます。
GitLab Self-Managedの管理者は、この設定をオーバーライドして適用できます。この設定が適用されると、CI/CDジョブトークンは常にプロジェクトの許可リストに制限されます。
ジョブトークン許可リストにグループまたはプロジェクトを追加する
ジョブトークン許可リストにグループまたはプロジェクトを追加すると、ジョブトークンによる認証を通じてプロジェクトのリソースへのアクセスを許可できます。デフォルトでは、プロジェクトの許可リストにはそのプロジェクト自体のみが含まれています。クロスプロジェクトアクセスが必要な場合にのみ、グループまたはプロジェクトを許可リストに追加します。
許可リストにプロジェクトを追加しても、許可リストに登録されたプロジェクトのメンバーに追加の権限が付与されるわけではありません。許可リストに登録されたプロジェクトのジョブトークンを使用してプロジェクトにアクセスするには、プロジェクト内のリソースにアクセスする権限がそのユーザーにすでに付与されている必要があります。
たとえば、プロジェクトAの許可リストにプロジェクトBを追加するとします。これにより、プロジェクトB(「許可されたプロジェクト」)のCI/CDジョブは、CI/CDジョブトークンを使用してAPIコールを認証し、プロジェクトAにアクセスできるようになります。
前提条件:
- 現在のプロジェクトでメンテナーまたはオーナーロールが必要です。許可されたプロジェクトが内部またはプライベートの場合、そのプロジェクトでゲスト、プランナー、レポーター、デベロッパー、メンテナー、またはオーナーロールが必要です。
- 許可リストに追加できるグループとプロジェクトの数は最大で200です。
グループまたはプロジェクトを許可リストに追加するには、次のようにします。
- 上部のバーで、検索または移動先を選択して、プロジェクトを見つけます。
- 左サイドバーで、設定 > CI/CDを選択します。
- ジョブトークンの権限を展開します。
- CI/CDジョブトークン許可リストの右側にある追加を選択します。
- グループまたはプロジェクトを選択します。
- 許可リストに追加するグループまたはプロジェクトへのパスを入力して、追加をクリックします。
APIを使用してグループまたはプロジェクトを許可リストに追加することもできます。
公開プロジェクトまたは内部プロジェクトのジョブトークンのスコープを制限する
許可リストに含まれていないプロジェクトでも、ジョブトークンを使用して公開または内部プロジェクトに対して認証し、次の操作を行えます。
- アーティファクトのフェッチ。
- コンテナレジストリへのアクセス。
- パッケージレジストリへのアクセス。
- リリース、デプロイ、環境へのアクセス。
- リポジトリにアクセスします。
各機能をプロジェクトメンバーのみに表示されるよう設定することで、これらのアクションへのアクセスを、許可リストに含まれるプロジェクトのみに制限できます。
前提条件:
- プロジェクトのメンテナーロールを持っている必要があります。
機能をプロジェクトメンバーのみが表示できるように設定するには、次のようにします。
- 上部のバーで、検索または移動先を選択して、プロジェクトを見つけます。
- 左側のサイドバーで、設定 > 一般を選択します。
- 可視性、プロジェクトの機能、権限を展開します。
- アクセスを制限する機能の表示レベルをプロジェクトメンバーのみに設定します。
- アーティファクトをフェッチする機能は、CI/CDの表示レベルの設定によって制御されます。
- 変更を保存を選択します。
すべてのプロジェクトから自分のプロジェクトへのアクセスを許可する
- 提供形態: GitLab Self-Managed、GitLab Dedicated
トークンアクセス制限と許可リストを無効にすると、セキュリティリスクになります。悪意のあるユーザーが、許可されていないプロジェクトで作成済みのパイプラインを侵害しようとする可能性があります。パイプラインがいずれかのメンテナーによって作成された場合、プロジェクトへのアクセスを試みるためにジョブトークンが悪用される可能性があります。
CI/CDジョブトークン許可リストを無効にすると、どのプロジェクトのジョブからでも、ジョブトークンを使用してプロジェクトにアクセスできるようになります。パイプラインをトリガーするユーザーには、プロジェクトにアクセスする権限が必要です。この設定を無効にするのはテストや同様の目的に限定し、可能な限り速やかに再度有効にする必要があります。
このオプションを利用できるのは、全プロジェクトでジョブトークン許可リストを有効にして適用する設定が無効になっているGitLab Self-ManagedまたはGitLab Dedicatedインスタンスのみです。
前提条件:
- プロジェクトのメンテナーまたはオーナーロールが必要です。
ジョブトークン許可リストを無効にするには、次のようにします。
- 上部のバーで、検索または移動先を選択して、プロジェクトを見つけます。
- 左サイドバーで、設定 > CI/CDを選択します。
- ジョブトークンの権限を展開します。
- 全グループとプロジェクトを選択します。
- 推奨。テストが完了したら、このプロジェクトと許可リスト内のグループとプロジェクトのみを選択して、ジョブトークン許可リストを再度有効にします。
この設定は、GraphQL(inboundJobTokenScopeEnabled)またはREST APIでも変更できます。
プロジェクトリポジトリへのGitプッシュリクエストを許可する
CI/CDジョブトークンで認証するGitプッシュリクエストを許可するようにプロジェクトを設定できます。この設定はデフォルトでオフになっています。
この設定をオンにすると、プロジェクトのパイプラインで実行されるCI/CDジョブによって生成されたCI/CDジョブトークンのみを、プロジェクトにプッシュできます。
CI/CDジョブトークンを使用してプロジェクトにプッシュする場合、CI/CDパイプラインはトリガーされることはありません。CI/CDジョブトークンには、ジョブを開始したユーザーと同じアクセス権限があります。
semantic-releaseツールを使用する場合、この設定によりパイプラインの作成が妨げられる可能性があります。
前提条件:
- プロジェクトのメンテナーまたはオーナーロールが必要です。
プロジェクトで生成されたジョブトークンにプロジェクトのリポジトリにプッシュする権限を付与するには、次のようにします。
- 上部のバーで、検索または移動先を選択して、プロジェクトを見つけます。
- 左サイドバーで、設定 > CI/CDを選択します。
- ジョブトークンの権限を展開します。
- 権限セクションで、リポジトリへのGitプッシュリクエストを許可するを選択します。
設定は、projects APIのci_push_repository_for_job_token_allowedパラメータでも制御できます。
許可リストにあるプロジェクトからの、プロジェクトをまたぐGitプッシュリクエストを許可する
許可リストにあるプロジェクトからのCI/CDジョブトークンが、プロジェクトのリポジトリにプッシュすることを許可できます。これは、GitOpsワークフロー、サブモジュールのタグ付け、および長期間有効なアクセストークンを使用しないクロスプロジェクトCI/CDパイプラインに役立ちます。
CI/CDジョブトークンのプッシュが成功した場合、ターゲットプロジェクトでCI/CDパイプラインはトリガーされることはありません。
プルミラーとして設定されたプロジェクトでは、この設定を有効にしないでください。パイプラインがミラーの更新のためにトリガーされる場合は特にそうです。許可リストにあるソースプロジェクトのオーナーが、CI/CDジョブトークンを使用して、コミットをミラーされたプロジェクトにプッシュする可能性があります。
クロスプロジェクトプッシュが機能するためには、次のすべてが真である必要があります:
- ターゲットプロジェクトでリポジトリへのGitプッシュリクエストを許可するが有効になっていること。
- ターゲットプロジェクトで許可リストにあるプロジェクトからの、プロジェクトをまたぐGitプッシュリクエストを許可するが有効になっていること。
- ターゲットプロジェクトでCI/CDジョブトークン許可リストが有効になっていること。
- ソースプロジェクトが
admin_repositories詳細な権限を持つターゲットプロジェクトの許可リストにあるか、またはデフォルトの権限(詳細な制限が設定されていない)を持っていること。ソースプロジェクトを含む許可リスト上のグループエントリも、この要件を満たします。 - パイプラインを開始したユーザーが、ターゲットプロジェクトで少なくともデベロッパーロールを持っていること。
前提条件:
- プロジェクトのメンテナーまたはオーナーロールが必要です。
クロスプロジェクトプッシュリクエストを許可するには:
- 上部のバーで、検索または移動先を選択して、プロジェクトを見つけます。
- 設定 > CI/CDを選択します。
- ジョブトークンの権限を展開します。
- 権限セクションで、リポジトリへのGitプッシュリクエストを許可するを選択します。
- 許可リストにあるプロジェクトからの、プロジェクトをまたぐGitプッシュリクエストを許可するを選択します。
- 変更を保存を選択します。
- ソースプロジェクトまたはそのグループを許可リストに追加するときは、
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ジョブトークンを使用して自分のプロジェクトに対して認証しているかは、認証ログで追跡できます。ログを確認するには、以下を実行します。
- 上部のバーで、検索または移動先を選択して、プロジェクトを見つけます。
- 左サイドバーで、設定 > CI/CDを選択します。
- ジョブトークンの権限を展開します。認証ログセクションには、ジョブトークンで認証してプロジェクトにアクセスした他のプロジェクトのリストが表示されます。
- オプション。認証ログ全体をCSV形式でダウンロードするには、CSVをダウンロードをクリックします。
認証ログには、最大100件の認証イベントが表示されます。イベント数が100件を超える場合は、CSVファイルをダウンロードしてログを確認してください。
プロジェクトへの新しい認証が認証ログに表示されるまで、最長5分かかる場合があります。
CI/CDトークンのレガシー形式を使用する
GitLab 19.0以降、CI/CDジョブトークンはデフォルトでJWT(JSON Webトークン)標準を使用しています。プロジェクトのトップレベルグループを設定すると、プロジェクトでレガシー形式を引き続き使用できます。この設定が利用できるのは、GitLab 20.0リリースまでです。
CI/CDトークンのレガシー形式を使用するには、次のようにします。
- 上部のバーで、検索または移動先を選択して、グループを見つけます。
- 左サイドバーで、設定 > CI/CDを選択します。
- 一般パイプラインを展開します。
- 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エラーで失敗する可能性があります。これは次の状況で発生する可能性があります:
エラーは通常、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にアップデートしてください。