2021年12月06日 - Tomo Masakura    

GitLabのアクセストークンの安全な選び方・使い方

GitLabで使える様々なアクセストークンの解説と安全に使う方法。

GitLabにはパーソナルアクセストークンやプロジェクトアクセストークンや他にも何種類もアクセストークンがあります。どれを使ったらいいか悩みませんか?

このブログではそれぞれのアクセストークンを簡単に説明し、アクセストークンを使う際の注意点や、どのアクセストークンを使ったほうが安全になるかを解説します。

アクセストークンとは?

GitLabのリソース(例:プロジェクト・リポジトリ・イシューなど)へのアクセスは通常、ウェブ画面からユーザー名とパスワードでログインしてウェブ画面でアクセスします。GitLabはパスワードの他にもアクセストークンを利用したアクセスも提供しています。このアクセストークンは主に次の用途で使われます。

  • GitpodのようなGitLabと連携するサービスからGitLabリソースへのアクセスするため
  • CI/CDジョブからGitLabリソースへのアクセスするため
  • Gitなどのあなたが利用している開発ツールからGitLabリソースへアクセスするため

アクセストークンは次の点でパスワードと異なります。

  • アクセス制限ができる - アクセストークンはAPI呼び出しのみや、Gitリポジトリへのアクセスのみなどのアクセス制限をかけられます。もしアクセストークンが漏洩した場合でも、パスワードと異なり、被害を軽減することができます。
  • 個別に発行する - アクセストークンは外部サービスや開発ツールごとに個別に発行します。使わなくなったサービス・ツールなどのアクセストークンを個別に無効化し、確実にサービス・ツールからGitLabリソースへアクセスできないようにできます。パスワードで同じことをするためには、パスワードを変更し、継続して利用するサービスすべてのパスワードを更新する必要があります。
  • 類推されにくい - アクセストークンはGitLabがランダムで十分な長さの安全なな文字列を発行します。人間が覚えなければならないパスワードと比べると、強度が高めです。
  • 2FAが不要 - 今では安全のため多要素認証を有効にすることが求められます。アクセストークンによるアクセスではこの2FAが不要です。

GitLabでは次のケースでアクセストークンが利用できます。

  • GitLab API
  • Gitリポジトリ
  • コンテナリポジトリ
  • パケージレジストリ

GitLabのアクセストークン

GitLabのアクセストークンは次の表のように何種類もあります。それぞれアクセスできるプロジェクトの範囲や、APIやGitアクセスがが利用できるできないなど、特性が異なります。

  パーソナルアクセストークン プロジェクトアクセストークン デプロイトークン CI/CDジョブトークン OAuth2トークン パスワード (参考)
Git リポジトリ △ (*1)
API × △ (*2) ×
コンテナレジストリ
パッケージレジストリ △ (*3) ×
作成方法 手動 手動 手動 暗黙的 暗黙的  
範囲 ユーザー プロジェクトまたはグループ プロジェクトまたはグループ ユーザー ユーザー  
  • *1 Gitプッシュはできません
  • *2 一部のAPIのみ呼び出せます
  • *3 NuGetなど、使えないパッケージがあります

動けばいいやで適当にアクセストークンを使っていると、アクセストークンが漏洩したときの被害が大きくなります。漏洩しないような対策はもちろんですが、漏洩したときに被害を抑えるために、なるべく適切で最小限の権限を持つアクセストークンを選ぶことが重要です。

余談ですが、これらの他にも特殊用途用のトークンがあります。例えば、フィードトークンやGitLabの正常性チェック用のトークンなどです。このブログの範疇からは外れるので、省略しています。

パーソナルアクセストークン

パーソナルアクセストークンによるアクセスは、その名前の通り、パーソナルアクセストークンの作成者によるものとみなします。つまり、そのユーザーが参加しているすべてのプロジェクトやグループにアクセスできます。

もし、アクセストークンが漏洩すると、被害が広範囲に及ぶことになります。

例えば、Aさんは請負で別々の会社(甲・乙・丙・丁)のお仕事を請け負っているとします。それらはGitLab.comで開発されています。Aさんは会社甲の開発のためにパーソナルアクセストークンを発行しました。もし、このアクセストークンが漏洩した場合、会社甲のプロジェクトだけでなく、全く関係のない他の会社のプロジェクトも被害を受けるわけです。

このような関係のないプロジェクトへの巻き添えを防ぐために、パーソナルアクセストークンの使用は極力避け、代わりにプロジェクトアクセストークンなどの他のアクセストークンを使用してください。

ただし、例外的にパーソナルアクセストークンを使ったほうがいいケースがあります。あなたの開発環境で、Gitリポジトリにアクセスする場合は、パスワードの代わりにGitリポジトリへのアクセスのみを許可したパーソナルアクセストークンを使うことをおすすめします。もしパーソナルアクセストークン漏洩しても、パスワードと異なり、Gitリポジトリにしかアクセスできません。コンテナレジストリやパッケージレジストリのアクセスも同様です。

なお、2FAを有効にしている、もしくはSNS認証でログインしていてパスワード無しになっている場合は、パスワードではGitリポジトリやコンテナレジストリにアクセスできません。パーソナルアクセストークンを使用してください。

作成する

  1. GitLabのトップメニューの右側のユーザーアイコンから、Preferencesをクリックします
  2. 左のサイドメニューのアクセス トークンを選択します
  3. Token nameにわかりやすい名前を入力します
  4. 必要に応じて有効期限を設定します
  5. Select scopesから必要な権限を選びます
  6. Create personal access tokenをクリックして、アクセストークンを作成します

パーソナルアクセストークン管理画面

パーソナルアクセストークンが作成され、一度だけ表示されます。アクセストークンをメモしたりせずに、CI/CD変数やアクセストークンを利用するツールに直接コピペしてください。パーソナルアクセストークンは何度でも作成できるため、使い回しをせずに、都度作成します。

パーソナルアクセストークンは次の表のようにスコープでアクセスできるGitLabリソースに制限をかけられます。

Scope read write 機能
api read write API、コンテナレジストリ、パッケージレジストリ
read_user read only API (/userエンドポイント(*1)、/usersエンドポイントのみ)
read_api read only API、コンテナレジストリ、パッケージレジストリ
read_repository read only Gitリポジトリ
write_repository read write Gitリポジトリ
read_registry read only コンテナレジストリ (パッケージレジストリは不可)
write_registry write only (*2) コンテナレジストリ (パッケージレジストリは不可)
  • *1 /userエンドポイントは、パーソナルアクセストークンを作成したユーザーの非公開情報を含むプロフィールを返します
  • *2 write_registryだけで書き込みができるようにヘルプには書いてありますが、実際にはread_registryも有効にしないと、書き込みすらできません

スコープは必要最小限にとどめます。よく分からないからと、スコープすべてを有効にしてはいけません。

利用する

Gitリポジトリやコンテナレジストリ、パッケージレジストリへのアクセスは、パスワードの代わりにパーソナルアクセストークンを利用できます。ユーザー名はあなたのユーザー名を利用します。(実際には、Gitリポジトリアクセスははユーザー名はなんでも良いのですが、パッケージレジストリのようにあなたのユーザー名でないといけないものもありますので、あなたのユーザー名で統一したほうが良いでしょう)

$  git clone https://gitlab.example.jp/user1/project1.git
Cloning into project1'...
Username for '...': <your name>
Password for '...': <personal access token>

コンテナレジストリやパッケージレジストリでのアクセストークンの使い方は公式ドキュメントをご覧ください。

APIアクセスは、PRIVATE-TOKEN:ヘッダーでパーソナルアクセストークンを送信します。

curl --header "PRIVATE-TOKEN: <personal access token>" https://gitlab.example.jp/api/v4/projects

その他のAPIアクセスの方法はPersonal/project access tokensをご覧ください。

プロジェクトアクセストークン

プロジェクトアクセストークンは、パーソナルアクセストークンとよく似ていますが、次の点で異なります。

  • プロジェクト専用のアクセストークンとなります。つまり、プロジェクトアクセストークンの漏洩で関係のないプロジェクトを巻き込むことがありません。
  • 対になるボットユーザーが作られます。ボットユーザーはプロジェクトメンバーで確認できます。
  • スコープだけでなく、ロール(Mainterner / Developer など)での制限もできます。

作成する

プロジェクトアクセストークンの作成は、GitLabプロジェクトのサイドメニューから設定->アクセストークンから操作することを除けば、パーソナルアクセストークンとほぼ同じです。違いは、スコープだけでなく、ロール(Mantiener / Developerなど)も設定できるところくらいです。スコープに加えて、適切なロールを設定してください。

プロジェクトアクセストークン管理画面

利用する

プロジェクトアクセストークンの使い方は、パーソナルアクセストークンと同じです。ただし、ユーザー名にはあなたのユーザー名ではなく、ボットユーザーのユーザー名を利用します。ボットユーザーのユーザー名はそのプロジェクトのメンバー一覧で確認できます。スクリーンショットにあるroject_4_bot1などがボットユーザーのユーザー名になります。

プロジェクトメンバー管理画面

GitLab.com

GitLab.comではプロジェクトアクセストークンが使えません。代わりにデプロイトークンを利用します。ただし、次の場合はデプロイトークンでは代用できません。

  • GitLab API
  • Gitリポジトリへのプッシュ

この場合でも、あなたのパーソナルアクセストークンの利用は避けてください。代わりに、そのプロジェクトにしか参加していないボットユーザーを作成し、そのボットユーザーのパーソナルアクセストークンを作成して利用します。

グループアクセストークン

GitLabにはグループアクセストークンもあります。プロジェクトアクセストークンのグループ版なのですが、GitLabの管理者しか作成できません。どうしても作りたい方は公式ドキュメントのCreate a group access tokenをご覧ください。

デプロイトークン

デプロイトークンはプロジェクトアクセストークンと同じく、特定のプロジェクト専用です。しかし、次の点で異なります。

  • APIアクセス及び、Gitリポジトリへのプッシュができません。
  • コンテナレジストリとパッケージレジストリへのアクセス許可を別々に設定できます。
  • 対になるユーザー名が作成されますが、プロジェクトアクセストークンと異なり、ボットユーザーは作られません。

プロジェクトアクセストークンで代替できるため、わざわざデプロイトークンを使う理由はあまりありません。ただし、GitLab.comではプロジェクトアクセストークンが利用できませんので、デプロイトークンを利用することになります。

作成する

デプロイトークンはプロジェクト固有のアクセストークンですので、プロジェクトのサイドメニューから設定->リポジトリ->Deploy tokensを選びます。スコープの種類がパーソナルアクセストークンとは異なります。

デプロイトークン管理画面

Scope read write 機能
read_repository read only Gitリポジトリ
read_registry read only コンテナレジストリ
write_registry (*1) コンテナレジストリ
read_package_registry read only パッケージレジストリ
write_package_registry read write (*2) パッケージレジストリ
  • *1 設定画面の説明では、読み書き両方できると書かれていますが、実際にはread_registryと組み合わせて初めて読み書きができます。なお、write_registryだけでは書き込みも失敗します。
  • *2 公式ヘルプでは書き込み専用、設定画面では読み書き両方できると書かれていますが、実際には読み書き両方ができます。

利用する

デプロイトークンの使い方は、プロジェクトアクセストークンやパーソナルアクセストークンと同じです。ただし、ユーザー名はデプロイトークンのユーザー名を利用します。デプロイトークンのユーザー名はデプロイトークンの設定画面で確認できます。

グループデプロイトークン

デプロイトークンは特定のグループ専用のグループデプロイトークンも作成できます。グループの設定から作成するところ以外はプロジェクトのデプロイトークンと同じです。

CI/CDジョブトークン

CI/CDジョブトークンは、その名前の通り、CI/CDジョブの中でだけで使われる特別なアクセストークンです。ジョブが開始されると自動で発行され、ジョブの完了とともに破棄されます。ジョブの中で勝手に使われているため、CI/CDを利用してれば、知らないうちにお世話になっています。

CI/CDジョブトークンはジョブをキックしたユーザーからのアクセスとしてみなされます。ですので、パーソナルアクセストークンと同様に、漏洩した場合に関係のない他のプロジェクトまで影響を及ぼします。ですが、寿命が短く一部のAPIにしかアクセスできませんので、パーソナルアクセストークンほど危険ではありません。

CI/CDジョブトークンは次の機能が使えます。

  • Gitリポジトリ
  • コンテナレジストリ
  • パッケージレジストリ
  • Releases API
    • 14.5 より前のバージョンでは、Release API の一部しか呼び出せないバグがありました。
  • 他にもいくつか利用できます。詳しくは公式ドキュメントのをご覧ください

もし、これ以外のAPIを呼び出す必要がある場合は、プロジェクトアクセストークンを利用してください。

利用する

CI/CDジョブで、$CI_JOB_TOKEN変数にプリセットされています。

Gitリポジトリへのアクセスやコンテナレジストリ、パッケージレジストリへのアクセスでは、パスワードの代わりにCI/CDジョブトークンを利用します。ユーザー名はgitlab-ci-token決め打ちです。

APIアクセスは注意が必要です。パーソナルアクセストークンで利用できるPRIVATE-TOKEN:ヘッダーは使えません。代わりにJOB-TOKEN:ヘッダーを使います。

curl --header "JOB-TOKEN: $CI_JOB_TOKEN" https://gitlab.example.jp/api/v4/releases

他のプロジェクトのCI/CDジョブトークンを受け入れない

CI/CDジョブトークンは寿命が短く、APIの呼び出しが制限されているとはいえ、関係のない他のプロジェクトにアクセスできるのはあまりいいことではありません。GitLab 14.4から、他のプロジェクトのCI/CDジョブトークンを受け入れない設定ができるようになりました。特定のプロジェクトのCI/CDジョブトークンのみ受け入れることもできます。

CI/CDジョブトークンの制限設定画面

この制限を有効にしたほうが良いでしょう。

CI/CDジョブでのアクセストークンの使い方

ジョブで利用するアクセストークンは、基本的にCI/CDジョブトークンを利用してください。ほとんどの場合はそれで問題はないと思います。

ですが、CI/CDジョブトークンでは呼び出せないAPIを呼び出すときなど、CI/CDジョブトークンでは不足する場合、別途プロジェクトアクセストークンを作成してそれを使ってください。

作成したアクセストークンはプロジェクト(やグループ)の設定にある、CI/CD変数に設定します。ここで設定した変数は、ジョブの中で利用できます。

CI/CD変数設定画面

  • Mask variableは必ず有効にしてください。これによって、ジョブのログにアクセストークンが表示されることを防げます
  • アクセストークンを必要としているジョブ以外では利用できないように、Protect variable及びEnvironment Scopeを適切に設定します

OAuth2トークン

パーソナルアクセストークンとプロジェクトアクセストークンはGitLabの設定画面よりあなたが作成してアクセストークンを取得し、それを利用することができます。CI/CDジョブトークンは自動で発行されますが、あなたがそれを利用することができます。それに対してOAuth2トークンは、連携する外部サービスに対して直接発行され、あなたがOAuth2トークンを取得することも、直接利用することもできません。

このブログで紹介している他のアクセストークンと異なり、直接使うことはありませんので、詳細な説明は割愛します。

しかし、OAuth2トークンはパーソナルアクセストークンと同じく、あなたがアクセスできるプロジェクトやグループ全てにアクセスできます。OAuth2トークンが漏洩した場合、パーソナルアクセストークンと同様に、関係のない他のプロジェクトまで巻き込んでしまうことを覚えておいてください。

OAuth2トークンの発行は、あなたが連携する外部サービスとの認可をGitLabで許可した後に発行されます。この許可をする画面で、どのスコープを許可するかを確認できます。

OAuth2認可画面

関係のない他のプロジェクトへの巻き添えを防ぐため、絶対に信頼できない外部サービスとの連携を許可しないでください

おまけ…

OAuth2トークンの詳細は割愛しました。しかし、OAuth2トークンの利用方法は仕様が分かりにくいため、調べるのに苦労しました。せっかくなのでメモ程度ですが残しておきます。

  • Gitリポジトリのユーザー名はoauth2決め打ちです。あなたのユーザー名は使えません。
  • コンテナレジストリのユーザー名もoauth2決め打ちです。また、スコープは必ずapiにしてください。(read_registrywrite_registryread_apiはおそらくなんの意味もありません)
  • パッケージレジストリは利用できない場合があります。例えば、npmではパーソナルアクセストークンの代わりにOAuth2トークンを使えますが、NuGetではOAuth2トークンを受け付けないようです。

まとめ

一口にアクセストークンといっても、GitLabにはたくさんあります。アクセストークンが漏洩しないようにすることも大事ですが、漏洩した後の被害を最小限に抑えることも大事です。

  • 信頼できない外部サービスとの連携は絶対にしてはいけません
  • パーソナルアクセストークンはアクセスできる範囲が広いので、極力利用を避けてください
  • アクセストークンの使い回しを避けます
  • アクセストークンはスコープ・ロール・期限などを用いて、必要最小限の権限に制限します
  • あなたのパソコンでの開発のためのGitリポジトリ・パッケージレジストリ・コンテナレジストリへのアクセスは、パスワードの代わりにパーソナルアクセストークンを使用することを推奨します

GitLab APIを呼び出す場合に利用するアクセストークンは、次のチャートを参考にします。

GitLab API

コンテナレジストリもしくはパッケージレジストリにアクセスする場合は、次のチャートを参考にします。

コンテナレジストリ及びパッケージレジストリ

Gitリポジトリにアクセスする場合は、次のチャートを参考にします。

Gitリポジトリ

CI/CD変数にアクセストークンを設定するときは次の点を気をつけます。

  • Mask Variableは必ず有効にします
  • Protect variableEnvironment scopeを利用して、必要最小限のジョブ以外にはアクセストークンを利用させないようにします
Gitlab x icon svg