本文へスキップ

GitHub Appのインストールトークンが520文字のJWTに

GitHub(ギットハブ)は10月2日、GitHub Appのインストールトークンをステートレス形式へ移行し終えました。長さは40文字から約520文字に増え、従来のチェックが動かなくなるおそれがあります。

著者 Tech AI Wire Team

3 分で読めます

2026年10月2日付のGitHub Changelogの記事「Stateless GitHub App installation tokens rolled out」のスクリーンショット。下にはGitHubの青いOctocatのアートワークがある。

数字で見る

characters in the old installation token
40
characters in the new stateless token
~520
when the opt-out header is deprecated
Nov 30

GitHubは、新たに作成されるすべてのGitHub Appインストールトークンを新しい「ステートレス」形式に切り替え終えたと、2026年10月2日の変更履歴(changelog)で発表しました。トークンは今もghs_で始まりますが、長さは40文字ではなく約520文字になりました。検証用のパターンやデータベースの列など、従来の長さを前提にしたコードは、正常なトークンを拒否したり途中で切り捨てたりするおそれがあります。

変更点

インストールトークンとは、GitHub Appがインストール先のリポジトリーで操作を行うために使う、有効期間の短いパスワードです。GitHubは2026年4月27日に、新形式の段階的な展開を始めました。10月2日の変更履歴によると、その展開は完了しました。そのため、新形式が現在のデフォルトです。

新しいトークンはJWT(JSON Web Tokenの略)です。内部に情報を持つ、署名付きの文字列です。GitHubの5月の変更履歴によると、2つの形式はドットの数で見分けられます。ステートレストークンにはドットが2つ含まれ、従来の不透明なトークンには1つもありません。

従来の形式新しい形式
プレフィックスghs_ghs_
長さ40文字(固定)約520文字(変動あり)
トークン内のドット02
有効期間1時間1時間(変更なし)

GitHubによると、権限、リポジトリーの範囲指定、1時間の有効期限は変わりません。変わったのは文字列の形だけです。

トークンに含まれる情報

流出した秘密情報を探すスキャナーであるMongoDBのKingfisherプロジェクトは、4月26日に登録したissueでこの形式を説明しています。そこではパターンをghs_APPID_JWTと表記しています。issueによると、JWTの部分には対象のインストールやアプリといった詳細に加え、基本的な検証用データが入っています。

このJWTは、GitHub自身の内部の発行者(issuer)が署名しています。Kingfisherのissueは、クライアントアプリがこれを検証しようとすべきではないとしています。あなたのコードにとって、トークンは不透明な文字列のままであるべきです。保存して送るものであり、決して解析するものではありません。

Kingfisherはまた、展開が完了したら、このトークンを検出する自身のルールを更新する必要があると指摘していました。従来の40文字の形に一致させている秘密情報スキャナーは、この変更の影響が最初に表れる場所の1つです。

オーバーライド用ヘッダーとその期限

GitHubは5月、インストールトークンを作成するリクエストに、一時的なヘッダーX-GitHub-Stateless-S2S-Tokenを追加しました。enabledを送ると、新形式のトークンが返ります。disabledを送ると、すでに移行済みのアプリでも従来形式のトークンが返ります。ヘッダーを付けなければ、デフォルトに従います。

この逃げ道は閉じようとしています。10月2日の変更履歴によると、このヘッダーは2026年11月30日に非推奨になります。その日以降、時間稼ぎのために従来形式に固定していたチームは、その選択肢を失います。

GitHubの5月の変更履歴は、GitHub Enterprise Cloudとそのデータ所在地(data residency)リージョンも対象に含めています。また、サーバー間(server-to-server)のAppトークンと並んで、ワークフローが使うActionsのGITHUB_TOKENも挙げています。

開発者にとっての意味

これらのトークンを固定長として扱っている箇所がないか、コードを検索してください。GitHubのガイダンスは、問題になりやすい4つの箇所を挙げています。長さのチェック、データベースの列の上限、ヘッダーの切り捨て、ログのパターンです。どれも、気づかれないまま失敗する可能性があります。40文字や255文字までしか入らない列はトークンを切り捨て、その後のAPI呼び出しは認証エラーのように見える形で失敗します。

次に、検証用のパターンを直しましょう。ghs_[A-Za-z0-9]{36}のようなパターンは、新しいトークンを拒否します。トークンが長くなり、ドットも含むようになったためです。GitHubの5月の変更履歴は、両方の形式に一致するghs_[A-Za-z0-9.\-_]{36,}を提案しています。自分のパターンは、実際のトークンではなく、それぞれの形の架空のサンプルを使って正規表現テスターで確認してください。

GitHubによると、保存先は少なくとも520文字を格納できる必要があります。これには、キャッシュ、シークレットストア、サイズ制限のある環境変数も含まれます。ログで秘密情報を伏せ字にしているなら、長くなったトークンも確実に伏せられるかテストしてください。そうしないと、有効な認証情報の一部が平文で残るおそれがあります。

この春にオーバーライド用ヘッダーをdisabledに設定したなら、11月30日までに削除する必要があります。まずenabledでテストし、それからヘッダーを削除してください。

出典

  1. Stateless GitHub App installation tokens rolled out - GitHub Changelog
  2. GitHub App installation tokens: Per-request override header - GitHub Changelog
  3. Upcoming changes to GitHub App installation tokens format - MongoDB Kingfisher on GitHub
  4. Generating an installation access token for a GitHub App - GitHub Docs
securityapiauthentication

関連記事

RFC 10008のIETF Datatrackerページ。HTTP QUERYメソッドのタイトル、著者、Proposed Standard(提案標準)というステータスが表示されている。
プログラミング

HTTP QUERYにはRFC 10008があるが、実装はほとんどない

RFC 10008は2026年6月、HTTPにQUERY(クエリ)メソッドを加えました。GETのように安全で冪等、POSTのようにリクエストボディを持ちます。それを実装しているものは、まだほとんどありません。