⭐️GitHub App: JWT / installation access token / registration token

参考(すべて公式):

「自作の Bot にリポジトリへ PR を立てさせたい」を例に。

秘密鍵 .pem(App 作成時に1度だけDL)
   │ RS256 で署名
   ▼
JWT(最大10分)  … 「この App 本人です」としか言えない。リポジトリは触れない
   │ POST /app/installations/{installation_id}/access_tokens
   ▼
installation access token(1時間・ghs_…)  … ここで初めてリポジトリを触れる
   │
   ▼
PR を立てる / git clone

なぜ2段階なのか

秘密鍵が一番危ないから。具体的には:

  • 期限が無い —— 自分で作り直すまで永久に有効
  • 全インストール先に効く —— 3つの org に入れていれば3つとも
  • 下位トークンを何度でも作れる —— これ1つあれば App のできること全部ができる

漏れたら App ごと乗っ取られ、止めるには鍵を再生成して全環境に配り直すしかない。だから秘密鍵はトークンを作るときだけ使い、毎回のAPI呼び出しには「10分で切れる JWT」「1時間で切れる・そのインストール先しか触れないトークン」を使う。下に降りるほど、漏れたときの被害が小さくなる。

期限できること
秘密鍵 (.pem)無期限JWT に署名する
JWT最大10分App 自身の情報 / 次のトークンの発行
installation access token1時間そのインストール先のリポジトリ操作

期限は自分で決められない。公式がこう定めている。

Your JWT must be signed using the RS256 algorithm. (exp は)The time must be no more than 10 minutes into the future.

Installation access tokens expire after 1 hour.

これは何の技術?

machine-to-machine (M2M) 認証 —— 人間が出てこない、サービス同士の認証。

registration token は別物

名前が似ているだけで上の流れとは無関係。GitHub Actions の self-hosted runner を登録する整理券。

Use this token to register a runner on a repository. (…) The token expires after one hour.

installation access token(または PAT)
   │ POST /repos/{owner}/{repo}/actions/runners/registration-token
   ▼
registration token(1時間)
   │ ./config.sh --url https://github.com/owner/repo --token <token>
   ▼
runner が登録される

まとめ: JWT = トークンを取りに行くためだけのもの / installation access token = 普段API を叩くのはこれ / registration token = runner 登録専用、系統が違う。