GitHub REST API についてまとめています。

GitHub REST API は gh api と REST API(curl)でリクエストできます。

gh api と curl は、どちらも同じ GitHub REST API(https://api.github.com/...)を呼んでいます。
違いをまとめます。

比較

GitHub のプロジェクトに設定された Webhook の情報を取得する想定です。

項目 gh api curl
呼び出す API GitHub REST API GitHub REST API
URL の書き方 repos/owner/repo/hooks(パスだけ) https://api.github.com/repos/owner/repo/hooks(完全な URL)
トークン 自動(GH_TOKEN → GITHUB_TOKEN → macOS キーチェーンの順に探す) 自分で Authorization: Bearer ... ヘッダーを付ける
使われるトークン macOS キーチェーンの gho_ トークン(OAuth App トークン) $GITHUB_TOKEN の中身(PAT など、自分で入れたもの)
Accept / API バージョンのヘッダー 自動で付く 自分で付ける
JSON の絞り込み --jq が組み込まれている 別途 jq が必要(brew install jq)
ページング --paginate で全ページまとめて取れる Link ヘッダーを見て、自分で次のページを取る
事前準備 gh auth login を一度実行するだけ PAT を発行して GITHUB_TOKEN に入れる

Webhook 情報を取得するコマンド

gh 版

# CircleCI の Webhook だけ
gh api repos/foo/bar/hooks \
  --jq '.[] | select(.config.url == "https://circleci.com/hooks/github") | {id, created_at, updated_at, active, events}'

# 全件を一覧で
gh api repos/foo/bars/hooks \
  --jq '.[] | [.id, .config.url, .created_at, .updated_at] | @tsv'

# 特定の Webhook 1 件だけ
gh api repos/foo/bars/hooks/606328225

REST(curl)版

# CircleCI の Webhook だけ
curl -s \
  -H "Authorization: Bearer $GITHUB_TOKEN" \
  -H "Accept: application/vnd.github+json" \
  -H "X-GitHub-Api-Version: 2022-11-28" \
  https://api.github.com/repos/foo/bars/hooks \
| jq '.[] | select(.config.url == "https://circleci.com/hooks/github") | {id, created_at, updated_at, active, events}'

# 全件を一覧で
curl -s \
  -H "Authorization: Bearer $GITHUB_TOKEN" \
  -H "Accept: application/vnd.github+json" \
  -H "X-GitHub-Api-Version: 2022-11-28" \
  https://api.github.com/repos/foo/bars/hooks \
| jq -r '.[] | [.id, .config.url, .created_at, .updated_at] | @tsv'

# 特定の Webhook 1 件だけ
curl -s \
  -H "Authorization: Bearer $GITHUB_TOKEN" \
  -H "Accept: application/vnd.github+json" \
  https://api.github.com/repos/foo/bars/hooks/606328225

curl 版は、実行する前に GITHUB_TOKEN を設定してください。

export GITHUB_TOKEN=ghp_xxxx...          # Classic PAT(repo か read:repo_hook スコープ)
export GITHUB_TOKEN=github_pat_xxxx...   # Fine-grained PAT(Webhooks: Read)
export GITHUB_TOKEN=$(gh auth token)     # gh と同じトークンを使う場合

トークンの種類

GITHUB_TOKEN は環境変数の名前にすぎず、中身が PAT とは限りません。

GITHUB_TOKEN に入れるもの トークンの種類 先頭の文字
GitHub の Settings → Developer settings で発行したトークン PAT(Classic) ghp_
同上(Fine-grained) PAT(Fine-grained) github_pat_
gh auth token の出力 OAuth App トークン(PAT ではない) gho_
GitHub Actions が自動で用意するもの GitHub App のインストールトークン ghs_

Classic PAT と Fine-grained PAT の違い

一番の違いは、権限を絞れる細かさです。

項目 Classic PAT(ghp_) Fine-grained PAT(github_pat_)
対象リポジトリ 自分がアクセスできる全リポジトリに効く リポジトリを個別に指定できる(全部・選択・public のみ)
対象 Organization 所属するすべての Org にまたがって使える トークン 1 つにつき所有者(個人か Org)を 1 つだけ選ぶ
権限の単位 大まかなスコープ(例:repo = リポジトリへのほぼ全操作) 機能ごとに Read / Write を選べる(例:Webhooks は Read のみ)
有効期限 「無期限」も選べる 期限の指定が必須(Org のポリシーで上限を決められる)
Org 側の管理 SSO 認可のみ Org 管理者が承認制にしたり、一覧で見て取り消したりできる
対応している API ほぼ全部 一部まだ対応していない API がある(Packages、一部の Org 横断操作など)

Webhook 一覧を取るのに必要な権限は次のとおりです。

  • Classic:repo か read:repo_hook スコープ
  • Fine-grained:対象リポジトリを指定して Webhooks: Read

GitHub は Fine-grained を推奨しています。漏れたときの被害を小さくできるからです。

gh の認証情報の保存場所

gh auth login を実行すると、設定が次の 2 か所に保存されます。

保存場所 内容
~/.config/gh/hosts.yml ホストとアカウント名(トークン本体は入っていない)
macOS キーチェーン(サービス名 gh:github.com) トークン本体(gho_...)

gho_ トークンには有効期限がありません。次のどれかが起きるまで使えます。

  • gh auth logout を実行する
  • GitHub の Settings → Applications → Authorized OAuth Apps で「GitHub CLI」を取り消す
  • 1 年間使わない(自動で失効します)

補足

  • GITHUB_TOKEN を export すると、gh api もそちらを優先して使います
  • curl で gh と同じトークンを使いたいときは、$(gh auth token) をヘッダーに渡します
  • Webhook API で取れるのは作成日時(created_at)と更新日時(updated_at)です