GitHub Appsを運用している開発者・DevOpsエンジニア・プラットフォームチームは、GitHub App installation tokensを「40文字の固定長トークン」として扱っていないかをすぐ確認する必要があります。2026年4月24日のGitHub公式Changelogでは、GitHub App installation tokensが新しい形式へ段階的に移行することが告知されました。新形式ではghs_プレフィックスは維持されますが、トークン全体は約520文字の可変長になり、ghs_APPID_JWTのような構造に変わります。(The GitHub Blog)
結論として、対応の中心は「トークンを解析しない」「長さで検証しない」「保存領域とログ・スキャナーを見直す」の3点です。特に、正規表現でghs_[A-Za-z0-9]{36}のように判定しているコード、DBカラムを短く設計しているテーブル、CI/CDログのマスク設定、シークレットスキャンルールは優先して確認しましょう。
GitHub Appsの最新動向: GitHub App installation tokens will move to a new formatで何が変わったか
2026年4月24日に公開された「GitHub App installation tokens will move to a new format」は、GitHub Appsの認証処理に関わる重要な変更です。GitHubは、2026年4月27日から数週間かけて、新しく発行されるGitHub App installation tokensの形式を段階的に更新すると説明しています。目的は、トークン発行のパフォーマンス向上とAPI基盤の信頼性向上です。(The GitHub Blog)
変更の要点は次の通りです。
| 項目 | これまで問題になりやすい前提 | 2026年4月更新後の注意点 |
|---|---|---|
| トークン長 | ghs_を含めて40文字程度と想定している | 約520文字になり、内容によって長さが変わる |
| 形式 | ghs_ + 英数字の固定パターンとして扱う | ghs_APPID_JWT形式へ変更される |
| プレフィックス | ghs_でGitHub App installation tokenと判断する | ghs_プレフィックス自体は維持される |
| JWT部分 | デコード・検証して情報取得できると考える | クライアント側で検証すべきではなく、内容に依存してはいけない |
| 影響範囲 | GitHub Appsだけを見ればよいと考える | GitHub ActionsのGITHUB_TOKENも対象に含まれる |
GitHubは、installation tokenのJWT部分について、GitHub内部のissuerで署名されるものであり、クライアントアプリが検証したり中身に依存したりすべきではないと説明しています。つまり、新形式を「JWTだから読めるトークン」と捉えるのではなく、従来通り不透明な文字列として扱うことが重要です。(The GitHub Blog)
影響を受けるサービスと受けないサービス
今回の変更は、すべてのGitHub環境に一律で適用されるものではありません。GitHubの告知では、対象はGitHub Enterprise CloudとData Residency環境であり、GitHub Enterprise Serverは影響を受けないとされています。(The GitHub Blog)
| 対象 | 影響 |
|---|---|
| GitHub Enterprise Cloud | 対象 |
| GitHub Enterprise Cloud with Data Residency | 対象 |
| GitHub Enterprise Server | 対象外 |
| GitHub App installation server-to-server tokens | 対象 |
GitHub ActionsのGITHUB_TOKEN | 対象に含まれる |
| Copilot code review flowsで使われるuser-to-server tokens | 現時点では対象外。ただし今後詳細が共有される予定 |
GitHub Actionsを使っているチームも、今回の変更をGitHub Appsだけの話として扱わない方が安全です。GitHub Docsでは、GITHUB_TOKENはリポジトリにインストールされたGitHub Appのinstallation access tokenとして説明されています。ワークフロー開始時にジョブごとに発行され、権限はワークフローを含むリポジトリに限定されます。(GitHub Docs)
ロールアウト予定から逆算した対応期限
公式告知では、ロールアウトは大きく2段階に分かれています。
| 時期 | 対象 | チームが確認すべきこと |
|---|---|---|
| 2026年4月27日〜5月中旬 | GitHub ActionsのGITHUB_TOKEN、Dependabot、Slack、Teamsなどのファーストパーティ統合 | Actionsワークフロー、CI/CDログ、独自ラッパー、シークレットマスク設定 |
| 2026年5月中旬〜6月下旬 | すべてのGitHub App installation tokens | 自社GitHub Apps、外部連携、APIクライアント、DB、監視、運用手順 |
4月末から5月中旬までは、GitHub Actionsやファーストパーティ統合で早期に影響が見える可能性があります。その後、5月中旬から6月下旬にかけて、すべてのGitHub App installation tokensへ段階的に広がる予定です。GitHubは、広範な有効化の前にbrownout期間を設け、トークン形式に依存している統合を特定する方針も示しています。(The GitHub Blog)
実務上は、6月下旬まで待つのではなく、5月中旬までにコードと保存領域の一次監査を終えるのが現実的です。GitHub Actionsを大規模に使っている組織では、4月27日以降に一部ワークフローで先に兆候が出る可能性があります。
なぜ「40文字固定」の実装が危険なのか
GitHub App installation tokensは、APIリクエスト時のAuthorizationヘッダーに入れて使う認証情報です。GitHub Docsでは、installation access tokenを生成し、そのトークンをREST APIやGraphQL APIの認証に使う流れが説明されています。また、通常のinstallation access tokenは1時間で期限切れになります。(GitHub Docs)
問題は、これまでの運用で「ghs_から始まる40文字の文字列」として扱っていたコードや設定が残っている場合です。新形式では長さが約520文字になり、さらに可変長です。そのため、次のような処理は失敗しやすくなります。
| 危険な実装 | 起きる問題 |
|---|---|
token.length === 40で検証している | 新形式トークンを不正として弾く |
ghs_[A-Za-z0-9]{36}で正規表現チェックしている | ghs_APPID_JWT形式に一致しない |
DBカラムがVARCHAR(255) | トークンが途中で切れる、保存エラーになる |
| ログマスクが旧形式だけに対応 | 長いトークンがログに露出する |
| JWT部分をデコードしてinstallation IDを読む | 仕様外の依存になり、将来壊れる可能性がある |
特に見落としやすいのは、アプリ本体ではなく周辺処理です。APIクライアントでは問題なくても、監査ログ、エラーレポート、CI/CDのデバッグ出力、プロキシ、キュー、キャッシュ、A/Bテスト基盤などで固定長を前提にしていることがあります。
最初に確認すべき監査ポイント
パーサーとバリデーターを確認する
最優先で見るべきなのは、トークン文字列を検証・分解している箇所です。GitHubは、アクセストークンを特定の長さやハードコードされたパターンで検証しないよう推奨しています。公式告知でも、ghs_[A-Za-z0-9]{36}のような正規表現は新しいトークンに一致しない可能性があると説明されています。(The GitHub Blog)
避けるべき例は次のような実装です。
// 悪い例: 40文字固定を前提にしている
if (token.length !== 40) {
throw new Error("Invalid GitHub installation token");
}
// 悪い例: 旧形式の正規表現に依存している
const pattern = /^ghs_[A-Za-z0-9]{36}$/;
if (!pattern.test(token)) {
throw new Error("Invalid token format");
}
改善する場合は、トークンの中身ではなく、アプリケーション上必要な最低限の条件だけを確認します。
// 良い例: トークンを不透明な文字列として扱う
if (typeof token !== "string" || token.length === 0) {
throw new Error("GitHub installation token is required");
}
// 必要に応じてプレフィックス確認に留める
if (!token.startsWith("ghs_")) {
throw new Error("Unexpected GitHub token prefix");
}
ただし、プレフィックス確認すら必須ではありません。GitHub APIから発行されたトークンをそのままGitHub APIへの認証に使う設計なら、アプリ側で形式を細かく検証する必要はありません。検証しすぎるほど、将来の形式変更に弱くなります。
DB、キュー、キャッシュの文字列長を確認する
公式告知では、access tokenを保存するDBカラムが少なくとも520文字の文字列を格納できるようにすることが推奨されています。(The GitHub Blog)
確認すべき場所は、メインDBだけではありません。
| 保存先 | 確認する内容 |
|---|---|
| RDBMS | VARCHAR(40)、VARCHAR(255)、固定長CHARを使っていないか |
| NoSQL | スキーマ検証、バリデーションルール、暗号化前後のサイズ制限 |
| Redisなどのキャッシュ | 値の最大長、圧縮・暗号化処理の有無 |
| メッセージキュー | ペイロードサイズ、ログ出力、DLQ保存時のマスク |
| Secrets Manager | 値の長さ制限、バージョン管理、監査ログの表示範囲 |
| 分析基盤 | イベント属性の最大長、PII・secretマスクの設定 |
実務では、DBカラムを520文字ぴったりにするより、余裕を持たせる方が安全です。GitHubが「約520文字」「可変長」と説明している以上、将来の拡張も考えてTEXT型や十分な長さのVARCHARを検討するとよいでしょう。
ログ、監視、シークレットスキャンを確認する
長いトークンになると、ログや監視の扱いも変わります。旧形式だけをマスク対象にしていると、新形式のトークンがエラーログやCI/CDログに残るおそれがあります。
確認すべき設定は次の通りです。
| 領域 | 具体的な確認ポイント |
|---|---|
| アプリログ | Authorizationヘッダー、環境変数、例外メッセージを出していないか |
| CI/CDログ | set -x、デバッグ出力、テスト失敗時の環境変数ダンプ |
| APM | HTTPヘッダーやリクエスト属性を収集していないか |
| SIEM | 旧形式の検知ルールだけに依存していないか |
| Secret scanning | ghs_に続く長い文字列を検知・マスクできるか |
| チャット通知 | エラー通知にトークン断片が含まれないか |
ログマスクでは、完全一致のトークン文字列を登録する方式と、パターンで検知する方式があります。新形式では長さが変わるため、固定長のパターンだけでは不十分です。一方で、ghs_から始まる任意の長い文字列を広くマスクすると誤検知も増えます。運用では、Authorizationヘッダーを丸ごと記録しない、環境変数の値を出力しない、トークンは先頭数文字だけでも出さない、という設計に寄せる方が堅牢です。
GitHub Actionsの独自処理を確認する
今回の変更では、GitHub Actionsで使われるGITHUB_TOKENもロールアウト対象に含まれます。GitHub Docsでも、GITHUB_TOKENはGitHub App installation access tokenであり、各ワークフロージョブの開始時に作成されると説明されています。(GitHub Docs)
通常のワークフローでsecrets.GITHUB_TOKENや${{ github.token }}をAPI認証に渡しているだけなら、影響は限定的です。注意すべきなのは、次のような独自処理です。
# 注意が必要な例: トークン長をチェックしている
- name: Validate token
run: |
if [ ${#GITHUB_TOKEN} -ne 40 ]; then
echo "Invalid token"
exit 1
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
このようなチェックは、新形式で失敗する可能性があります。代わりに、API疎通で確認する方が実態に合っています。
# 改善例: 形式ではなくAPI疎通で確認する
- name: Check GitHub API access
run: |
curl -sSf \
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github+json" \
https://api.github.com/rate_limit > /dev/null
env:
GITHUB_TOKEN: ${{ github.token }}
形式チェックではなく、実際に必要なAPIへアクセスできるかをテストすることで、将来のトークン形式変更にも強くなります。
コードベースを効率よく洗い出す検索キーワード
大規模なリポジトリでは、すべての認証処理を目視で追うのは現実的ではありません。まずは、旧形式に依存していそうな文字列を機械的に検索します。
# ghs_を直接扱っている箇所を探す
rg "ghs_"
# 40文字固定のチェックを探す
rg "length\s*[=!]==?\s*40|size\s*[=!]==?\s*40"
# 旧形式に近い正規表現を探す
rg "A-Za-z0-9\]\{36\}|[a-zA-Z0-9]\{36\}|ghs_.*36"
# Authorizationヘッダーのログ出力を探す
rg "Authorization|authorization|Bearer"
# tokenという名前のカラム・変数を探す
rg "installation.*token|access.*token|github.*token"
検索時は、アプリケーションコードだけでなく、次の領域も対象に含めます。
| 対象 | 理由 |
|---|---|
| Terraform、Helm、Kubernetes manifests | Secretや環境変数の長さ・ログ出力に関係する |
| GitHub Actions workflow | GITHUB_TOKENを直接扱う可能性がある |
| テストコード | モックトークンが40文字固定で作られていることがある |
| SDKラッパー | 共通認証処理で形式チェックしていることがある |
| ログ・監視設定 | 旧形式だけをマスクしている可能性がある |
| DBマイグレーション | カラム長の制限を確認できる |
特にテストコードは見落としやすいポイントです。本番コードを修正しても、テスト用のダミートークンが40文字固定だと、変更後の挙動を正しく検証できません。新形式を模した長いダミー文字列を使い、トークンを保存・転送・マスクできるか確認しましょう。
具体的な対応手順
まず影響範囲を棚卸しする
最初に、GitHub App installation tokenをどこで発行し、どこに渡し、どこで保存しているかを整理します。おすすめは、トークンの流れを「入口」「保存」「利用」「観測」の4つに分けることです。
| 区分 | 確認する内容 |
|---|---|
| 入口 | GitHub APIからトークンを取得する処理、OctokitなどのSDK利用箇所 |
| 保存 | DB、キャッシュ、Secrets Manager、環境変数 |
| 利用 | REST API、GraphQL API、Git over HTTPS、外部連携 |
| 観測 | ログ、APM、監査、SIEM、通知、シークレットスキャン |
この分け方にすると、単に「コードを直す」だけでなく、運用上の漏れを減らせます。たとえば、トークンをDBに保存していないアプリでも、APMがHTTPヘッダーを収集していればログ漏えいリスクがあります。
固定長チェックを削除する
次に、40文字固定や旧正規表現に依存したチェックを削除します。GitHubが推奨している通り、トークンは不透明な文字列として扱うべきです。(The GitHub Blog)
判断基準はシンプルです。
| チェック内容 | 残すべきか |
|---|---|
| 空文字ではないか | 残してよい |
| 文字列型か | 残してよい |
ghs_で始まるか | 必要なら残す。ただし過信しない |
| 40文字か | 削除する |
ghs_ + 英数字36文字か | 削除する |
| JWT部分をデコードできるか | 削除する |
| JWTのclaimを業務ロジックに使うか | 削除する |
トークンの正当性は、形式ではなくGitHub APIへの認証結果で判断します。アプリ側で「正しそうな見た目」を保証しようとすると、今回のような形式変更のたびに壊れます。
保存領域を拡張する
DBや設定値にトークンを保存している場合は、少なくとも520文字を格納できることを確認します。実務では、暗号化やエンコードを挟むと保存時の文字列がさらに長くなる場合があります。
例として、次のようなカラムは見直し対象です。
-- 注意が必要な例
github_installation_token VARCHAR(40)
access_token VARCHAR(255)
token CHAR(40)
改善例です。
-- 例: 将来の拡張を考えて余裕を持たせる
github_installation_token TEXT
または、データベース方針としてTEXTを避けたい場合は、十分な長さのVARCHARを使います。
-- 例: 明示的に長さを確保する
github_installation_token VARCHAR(2048)
どちらを選ぶかは、DBの設計方針やインデックス要件によって変わります。ただし、access tokenそのものを検索キーにする設計は避けるべきです。照合が必要な場合は、トークンをそのまま保存・検索するのではなく、ハッシュ値や内部IDで管理する方が安全です。
ログマスクと検知ルールを更新する
新形式ではトークンが長くなるため、ログの見た目が大きく変わります。旧形式のghs_トークンだけを想定したマスクルールでは、JWT風の長い文字列が途中まで残る可能性があります。
安全側に倒すなら、次の方針が有効です。
| 方針 | 内容 |
|---|---|
| ヘッダーを記録しない | Authorizationヘッダーはログ対象から除外する |
| 値ではなくキーでマスクする | *_TOKEN、GITHUB_TOKEN、Authorizationなどキー名で伏せる |
| 例外メッセージに含めない | 認証失敗時もトークン値を出さない |
| CIのデバッグ出力を制御する | set -xや環境変数ダンプを避ける |
| 検知ルールを更新する | ghs_から始まる長い値もsecret候補として扱う |
ログマスクは「正規表現を賢くする」より、「そもそも出さない」方が安定します。トークンは認証情報であり、トラブルシュートに必要なのは多くの場合、トークンそのものではなく、発行時刻、installation ID、権限、APIレスポンスコード、リクエストIDです。
テストで新形式を想定する
公式告知では、今後ローカルで新しいトークンをテストするための追加ガイダンスを提供するとされています。(The GitHub Blog) それを待つだけでなく、自社側では長いダミー文字列を使って互換性テストを先に始められます。
テストでは、次の観点を確認します。
| テスト観点 | 確認内容 |
|---|---|
| 受け取り | 長いトークンを環境変数・引数・JSONで受け取れるか |
| 保存 | DB、キャッシュ、Secret Storeに欠損なく保存できるか |
| 転送 | APIクライアント、プロキシ、ジョブ間受け渡しで切れないか |
| マスク | ログ、CI、APM、通知で表示されないか |
| 失敗時 | 認証エラー時にトークンが例外や通知に出ないか |
ダミートークンは本物に似せる必要はありますが、本物のJWTとして成立させる必要はありません。重要なのは、長さ、区切り文字、ghs_プレフィックス、ピリオドを含むJWT風の文字列が、システム内で壊れず安全に扱われるかです。
チーム別の対応チェックリスト
開発者向け
| チェック | 完了目安 |
|---|---|
ghs_を直接扱うコードを検索した | すべての該当箇所を一覧化 |
| 40文字固定のチェックを削除した | length === 40が残っていない |
| 旧形式の正規表現を削除した | ghs_[A-Za-z0-9]{36}系が残っていない |
| JWT部分をデコードしていない | token splitやclaim参照がない |
| 長いダミートークンで単体テストした | 保存・転送・API呼び出し部分が通る |
開発者が特に注意したいのは、「親切なバリデーション」が障害原因になる点です。認証情報は、ユーザー入力のメールアドレスやURLとは違います。形式をアプリ側で強く縛るより、GitHub APIのレスポンスを信頼して処理する方が変更に強くなります。
DevOpsエンジニア向け
| チェック | 完了目安 |
|---|---|
| GitHub Actions workflowを確認した | GITHUB_TOKENの長さチェックがない |
| CI/CDログにトークンが出ない | デバッグ時もマスクされる |
| Secret Storeの値長制限を確認した | 約520文字以上を保存できる |
| デプロイ設定を確認した | 環境変数、Kubernetes Secret、Helm valuesで切れない |
| 監視・通知を確認した | エラー通知にトークンが含まれない |
DevOps領域では、アプリコードよりも「ログに出るか」「ジョブ間で壊れないか」が重要です。特にシェルスクリプトでトークンを一時ファイルに出す、echoで確認する、curlコマンドをそのままログに残す、といった運用は見直しましょう。
プラットフォームチーム向け
| チェック | 完了目安 |
|---|---|
| 社内共通SDKを確認した | トークン形式に依存していない |
| シークレットスキャンルールを更新した | 新形式を検知・マスクできる |
| DB標準設計を見直した | access token用カラム長の基準を更新 |
| 開発者向けガイドを更新した | 「トークンはopaque string」と明記 |
| 障害時の切り分け手順を作った | 認証失敗時に見るべき項目が整理済み |
プラットフォームチームは、個別アプリの修正だけでなく、社内の標準部品を優先して確認するべきです。共通SDKやテンプレートに40文字固定の前提があると、複数チームに同じ障害が広がります。
失敗しやすいポイント
「ghs_は変わらないから問題ない」と判断してしまう
今回、プレフィックスはghs_のままです。GitHub Docsでも、GitHub App installation access tokenのプレフィックスはghs_として整理されています。(GitHub Docs)
しかし、問題はプレフィックスではなく、その後ろの構造と長さです。ghs_で始まることだけを見ている処理は大きな影響を受けにくい一方、ghs_の後ろを固定文字数・固定文字種として扱っている処理は壊れる可能性があります。
JWTを読める情報源として使ってしまう
新形式にはJWTが含まれますが、クライアント側で検証したり、業務ロジックの情報源として使ったりしてはいけません。GitHubは、JWTにはトークンに関する情報が含まれるものの、クライアントアプリはその内容に依存すべきではないと説明しています。(The GitHub Blog)
たとえば、JWT部分からinstallation IDやapp IDを取り出して権限制御に使う設計は避けるべきです。必要な情報は、GitHub APIのレスポンスや自社DBで管理しているinstallation情報から取得しましょう。
DBだけ直してログを忘れる
トークン長変更の対応では、DBカラムの拡張に目が行きがちです。しかし、実際の漏えいリスクはログや監視から発生しやすくなります。新形式は長く、JWT風のドット区切りを含むため、既存のマスクルールが途中までしか隠さない可能性があります。
リリース前には、意図的に長いダミートークンを使って、CIログ、アプリログ、APM、通知、エラーレポートを確認してください。画面に1文字でもトークンが出るなら、マスク設定を見直すべきです。
GitHub Enterprise Serverも対象だと思い込む
今回の告知では、GitHub Enterprise Serverは影響を受けないとされています。(The GitHub Blog) ただし、GitHub Enterprise Serverを使っている企業でも、GitHub Enterprise CloudやGitHub Actions、外部SaaS連携を併用している場合があります。環境単位で切り分け、どのトークンがどの基盤で発行されているかを確認しましょう。
実務で使える対応優先度
限られた時間で対応する場合は、次の順番で進めると効果的です。
| 優先度 | 対応 | 理由 |
|---|---|---|
| 高 | 40文字固定・旧正規表現の削除 | 新形式で即時に認証処理が失敗する可能性がある |
| 高 | DB・Secret Storeの長さ確認 | トークン欠損は復旧に時間がかかる |
| 高 | ログマスク確認 | セキュリティ事故につながる |
| 中 | GitHub Actions workflow確認 | GITHUB_TOKENが早期ロールアウト対象に含まれる |
| 中 | テスト用ダミートークン更新 | 旧形式前提のテストを見つけやすい |
| 低 | ドキュメント更新 | 再発防止と社内展開に有効 |
緊急度が高いのは、認証失敗とトークン漏えいに直結する部分です。特に、共通ライブラリ、CI/CDテンプレート、ログ基盤は影響範囲が広いため、個別アプリより先に確認する価値があります。
2026年4月更新に対する推奨アクション
今回のGitHub App installation tokens新形式への移行は、APIの呼び出し方法そのものを大きく変えるものではありません。Authorization: Bearer <token>で使う基本的な流れは変わらず、GitHub App installation tokenとしての役割も同じです。変わるのは、トークンの見た目です。
そのため、対応の本質は次の3つに集約できます。
| やること | 具体策 |
|---|---|
| トークンを解析しない | 長さ、文字種、JWT claimに依存しない |
| 長い文字列として安全に扱う | DB、キュー、キャッシュ、Secret Storeを見直す |
| 露出させない | ログ、監視、CI/CD、通知のマスクを確認する |
まずは、ghs_、length === 40、ghs_[A-Za-z0-9]{36}、Authorization、GITHUB_TOKENをキーワードにコードベースと設定ファイルを検索してください。次に、保存領域が少なくとも520文字以上に対応できるかを確認し、最後に長いダミートークンでログ・監視・CI/CDを通したテストを行います。
GitHub Appsを安定運用するうえで、トークン形式は「仕様」ではなく「GitHubが発行する不透明な認証情報」として扱うべきです。今回の変更を機に、トークンの見た目に依存しない設計へ寄せておけば、今後の形式変更にも強い認証基盤になります。

コメント