GitHub Webhook:作成、署名検証、再配信
GitHub Webhook
GitHub Webhook:設定、イベント、署名の検証 | We.Inc
GitHub Webhookを作成してイベントを選び、動くコードでX-Hub-Signature-256ヘッダーを検証し、失敗した配信を再配信する方法。ブラウザー内で動く署名チェッカー付きです。
GitHub Webhookは、プッシュ、新しいIssue、リリースなど、リポジトリで何かが起きるたびにGitHubがサーバーのURLへ送るメッセージです。リポジトリの Settings、Webhooks から追加します。シークレットを設定しておけば、X-Hub-Signature-256 ヘッダーを確認して偽の配信を拒否できます。
知っておきたいGitHub Webhookの仕様(docs.github.com、2026年10月)
- 署名ヘッダー
- X-Hub-Signature-256、値は sha256= で始まる
- 署名方式
- シークレットをキーにしたSHA-256のHMAC(16進数ダイジェスト)
- 自動再試行
- なし。失敗した配信は自動では再配信されない
- ペイロードの上限
- 25 MB。これを超えるペイロードは配信されない
Webhookを使うと、GitHubは変更が起きた瞬間にサイトやアプリへ知らせてくれます。プッシュのたびにサイトを再ビルドしたり、Issueが作成されたらメッセージを投稿したり、リリース時に変更履歴を更新したりできます。手早いガイドの多くが省いている大切な点は、配信が本当にGitHubから来たものかを確認することです。下のチェッカーは、GitHubが送るのと同じ署名をブラウザー内で計算します。
- リポジトリを開き、Settings をクリックし、左のサイドバーの Webhooks、Add webhook の順にクリックします。
- Payload URL にエンドポイントを入力し、本文がそのままのJSONで届くようにコンテンツタイプとして application/json を選びます。
- Secret に長いランダムな文字列を入力し、同じ値をサーバーの環境変数にも保存します。
- Which events would you like to trigger this webhook で push イベントのみを選ぶか個別のイベントを選択し、Active にチェックを入れて保存します。
- GitHubはすぐに ping イベントを送ります。Recent Deliveries で確認し、サーバーが応答したことを確かめます。
- すばやく応答しましょう。10秒より遅い応答は失敗とみなされるため、すぐに2xxのステータスを返し、時間のかかる処理は後でバックグラウンドジョブとして行います。
- 署名は、JSONを解析する前の生の本文のバイト列に対して計算しましょう。解析して再シリアライズするとバイト列が変わり、検証に失敗します。
- 署名の比較には crypto.timingSafeEqual のような定数時間の関数を使い、単純な == での比較は使わないでください。
- 手動で再配信するときは、配信ごとに一意のIDである X-GitHub-Delivery を使って重複をスキップしましょう。
- 処理するイベントだけを購読しましょう。イベントが少ないほどサーバーへのリクエストが減り、守るべき範囲も小さくなります。
よくある質問
GitHubは失敗したWebhookを再試行しますか?
いいえ。GitHubのドキュメントには、失敗した配信を自動で再配信しないと明記されています。過去3日間の配信であれば、Recent Deliveries から手動で再配信できます。
X-Hub-Signature-256 ヘッダーとは何ですか?
Webhookにシークレットが設定されている場合に送られるヘッダーです。GitHubはリクエスト本文を取り、シークレットをキーにしてSHA-256でHMACを計算し、その16進数の結果に sha256= を付けて送ります。サーバー側でも同じ計算を行って比較します。
Webhookはどんなイベントを受け取れますか?
push、pull_request、issues、release、workflow_run など多数あります。X-GitHub-Event ヘッダーには各配信のきっかけになったイベント名が入り、フックを最初に作成したときには ping が届きます。
公開サーバーがなくてもWebhookをテストできますか?
GitHubがエンドポイントにPOSTするため、エンドポイントはインターネットから到達できる必要があります。ローカルで作業する場合は、パソコンに一時的な公開URLを割り当てるトンネリングツールを動かし、そのURLを Payload URL に使います。
WebhookとAPIのポーリング、どちらを使うべきですか?
Webhookは変更が起きるたびにそれを届けてくれます。ポーリングは一定間隔でAPIに問い合わせる方法です。APIの呼び出しはレート制限に数えられるため、リクエストが少なく、より早く届くWebhookのほうが有利です。
各配信で届くもの
- 配信はすべてPOSTで、その内容を示すヘッダーが付いています。X-GitHub-Event はイベント名、X-GitHub-Delivery は一意のID、X-GitHub-Hook-ID はWebhookの識別子で、User-Agent は常に GitHub-Hookshot/ で始まります。
- 本文はイベントのペイロードです。プッシュの場合はコミットとブランチの参照が含まれるため、デプロイスクリプトはビルド対象以外のブランチへのプッシュを無視できます。
検証コードをGitHubのテスト値で確かめる
- GitHubは、本番前にコードが正しいことを確かめられるよう、既知の入力を公開しています。シークレット It's a Secret to Everybody とペイロード Hello, World! からは、757107ea で始まる署名が得られるはずです。
- このページのチェッカーには、これらの値があらかじめ入っています。サーバーがこれらから同じ結果を計算できれば、検証コードは正しく動いています。
このExpressのルートは、生の本文を読み取り、シークレットでHMACを計算して定数時間で比較してから、ペイロードを信頼します。
express.raw はGitHubが署名したバイト列をそのまま保持します。シークレットはコードではなく環境変数から読み込みます。
配信ヘッダー
すべてのGitHub Webhook配信に付くヘッダー
- X-GitHub-Event
- push や issues などのイベント名
- X-GitHub-Delivery
- この配信の一意のID(GUID)
- X-GitHub-Hook-ID
- 送信したWebhookのID
- X-Hub-Signature-256
- sha256= と本文のHMAC。シークレットが設定されている場合のみ
- User-Agent
- 常に GitHub-Hookshot/ で始まる
Webhook署名チェッカー
シークレットと生のリクエスト本文を入力すると、GitHubが送る X-Hub-Signature-256 の値を確認できます。Web Crypto APIを使ってブラウザー内で動作し、何もアップロードされません。
Webhookのシークレット
生のリクエスト本文
受け取った署名ヘッダー(任意)
sha256=...
計算された署名
一致:この配信の署名は、そのシークレットと本文に対して有効です。
不一致:シークレット、本文のバイト列、またはヘッダーが異なります。
GitHubのテスト値を読み込む
GitHubのテスト値では、結果は次と一致するはずです:
無料で始める · クレジットカード不要
関連: ガイド|Webマーケティングと集客を学ぶ
製品
ご利用いただける方
機能
リソース
会社情報
サイトマップを見る