GitHub App のインストール トークンは約520文字に(ghs_APPID_JWT)、X-GitHub-Stateless-S2S-Token は2026年11月30日に効かなくなる
2026年10月2日から、GitHub App の新しいインストール トークンはすべてステートレスな形式 ghs_APPID_JWT です(GitHub の changelog・切り替えは4月27日に始まりました)。いまも ghs_ で始まりますが、長さは40文字ではなく約520文字で、ドットを2つ含みます。権限、対象のリポジトリ、1時間の有効期限、トークンを作る REST のエンドポイントは変わりません。ワークフローも、たとえば actions/create-github-app-token から新しい形式を受け取ります。壊れるのは古い形を前提にしたコードです:長さの上限、パターン、伏せ字のルール、列。2026年11月30日までは、リクエストのヘッダーで古い形式をまだ頼めますが、その後は GitHub が無視します。
見え方
- 長さの上限がトークンを断る。ある更新の補助プログラムは 1〜255 バイトのトークンしか受け付けず、アプリを通した更新がすべて「The request was refused: the token is malformed.」で失敗しました(Quartio-Studio/yulius #423)。AWS Amplify の API の
accessTokenは255文字が上限でした(amplify-hosting #4106)。いまのリファレンスでは 4,096 です。Terraform のaws_amplify_appは自分の側で255のまま確かめていました。4,096 への変更は11月3日に、AWS プロバイダーの v6.72.0 のマイルストーンで取り込まれました(terraform-provider-aws #49642)。 - 古い形式のパターンに合わない。ちょうど40文字、または
ghs_のあとに英数字36文字、といった確かめ方が、トークンを断るか、別のものとして扱います。 - 古い形式に合わせた伏せ字やシークレットの検出のルールが、トークンを見逃すか、最初の部分だけ隠して残りを見せる。10月には多くのプロジェクトが自分の伏せ字の処理でこれに気づきました。たとえば gitleaks のルール(melodic-software/standards #830)や、ある CLI の伏せ字(nils-cli #2339)です。
- 上限の小さい列、シークレットの保管、環境変数、プロキシが、トークンや
Authorizationのヘッダーを切り詰め、リクエストはトークンが違うかのように失敗する。
トークンを表に出さずに確かめる
ステートレスなトークンは約520文字でドットが2つ、古いトークンは40文字でドットはありません。ワークフローでは、id: app-token を付けた actions/create-github-app-token のステップのあとに:
- name: Token format
env:
TOKEN: ${{ steps.app-token.outputs.token }}
run: echo "length ${#TOKEN}, dots $(printf %s "$TOKEN" | tr -cd . | wc -c)"
出るのは長さとドットの数だけです。このアクションはトークンをシークレットとして登録するので、どちらの形式でもランナーはログで伏せます。確かめるべきなのは、自分のスキャナーやログの伏せ字の処理です。
ヘッダーと11月30日
X-GitHub-Stateless-S2S-Token は、インストール トークンを作るエンドポイント POST /app/installations/{installation_id}/access_tokens に付ける一時的なリクエストのヘッダーです(GitHub の changelog・2026年5月15日):
enabled:ステートレスなトークンを返す。disabled:古い、ステートフルなトークンを返す。- 付けない、またはほかの値(
trueや0など):ふだんの動きで、いまはステートレスなトークンです。
GitHub は2026年11月30日にこのヘッダーを受け付けなくなります。その日から、disabled を付けたリクエストもステートレスなトークンを受け取ります。長さの上限のあるシステムのために disabled で短いトークンを保っているコードはその日に動かなくなるので、先にそのシステムを直します。そういうコードを探すには:
grep -rn 'X-GitHub-Stateless-S2S-Token' .
アプリが両方の形式で動くことを確かめたら、11月30日より前に本番のコードからヘッダーを外すように、と GitHub は書いています。
直し方
- インストール トークンは中身の分からない文字列として扱う:長さを決めず、解析しない。
- 列、シークレットの保管、設定、ヘッダーの上限は、新しい形式についての GitHub の案内のとおり、少なくとも520文字を受け付けるようにする。長さは一定ではないので余裕を持たせます。
- パターンが要るなら、GitHub は両方の形式に合うものを勧めています:
ghs_[A-Za-z0-9\.\-_]{36,}。 - 伏せ字とシークレットの検出のルールを、ドットとアンダースコアを含むトークン全体に合うように直す。
- Terraform で AWS Amplify を使うなら、上限が 4,096 の AWS プロバイダーにする(上のマイルストーンでは v6.72.0 以降)。
見分け方
- トークンが切られる、形が違うとして断られる、パターンに合わない、そして短いトークンなら通る:新しい形式で、このページです。
- 長さの合ったトークンで「Bad credentials」(HTTP 401):トークンが1時間で切れたか、取り消された(「Bad credentials」)。
- 「Resource not accessible by integration」(HTTP 403):トークンは効いていて、権限が足りない(「Resource not accessible by integration」)。
失敗したジョブを IntelliJ IDEA から見るなら
Pipeline Inbox for GitHub Actions Workflows は、Lesstep が作っている JetBrains IDE(2024.1 以降)のプラグインです。すべてのリポジトリの実行を、ジョブ・ステップと一緒に IDE のツールウィンドウに並べるので、GitHub の側の変更のあとに失敗しはじめたステップがすぐ分かり、いまのブランチの実行はステータスバーに出ます。読むのは無料、失敗したジョブの再実行・キャンセル・ワークフローの実行・デプロイのレビューは Pro(月 US$1.50・30日の無料試用つき)です。
GitHub と GitHub Actions は GitHub, Inc. の商標、IntelliJ IDEA は JetBrains s.r.o. の商標、AWS と AWS Amplify は Amazon.com, Inc. またはその関連会社の商標、Terraform は HashiCorp, Inc. の商標です。このページはそのいずれとも提携しておらず、承認も受けていません。
ほかに:「Bad credentials」 · 「Resource not accessible by integration」 · IntelliJ IDEA で使える GitHub Actions のプラグインの比較 · English