Webhook GitHub: Configurazione, Eventi e Verifica della Firma | We.Inc
Crea un webhook GitHub, scegli gli eventi, verifica l'header X-Hub-Signature-256 con codice funzionante e reinvia le consegne fallite. Include un verificatore di firma nel browser.
Un webhook GitHub è un messaggio che GitHub invia all'URL del tuo server ogni volta che succede qualcosa in un repository, come un push, una nuova issue o una release. Lo aggiungi in Settings, Webhooks del repository. Imposta un secret così puoi controllare l'header X-Hub-Signature-256 e rifiutare le consegne false.
Dati utili sui webhook GitHub (docs.github.com, ottobre 2026)
Elemento
Cosa documenta GitHub
Header della firma
X-Hub-Signature-256, il valore inizia con sha256=
Metodo di firma
Digest esadecimale HMAC con SHA-256, con il tuo secret come chiave
Tempo di risposta
Oltre 10 secondi viene registrato come consegna fallita
Tentativi automatici
Nessuno; le consegne fallite non vengono reinviate automaticamente
Reinvio manuale
Consegne degli ultimi 3 giorni
Limite di dimensione del payload
25 MB; i payload più grandi non vengono consegnati
I webhook permettono a GitHub di avvisare il tuo sito o la tua app dei cambiamenti nel momento in cui avvengono, così puoi ricostruire un sito a ogni push, pubblicare un messaggio quando si apre una issue o aggiornare un changelog a ogni release. La parte importante che la maggior parte delle guide rapide salta è verificare che una consegna arrivi davvero da GitHub. Il verificatore qui sotto calcola la stessa firma che invia GitHub, direttamente nel tuo browser.
Apri il repository, fai clic su Settings, poi su Webhooks nella barra laterale sinistra, poi su Add webhook.
Scrivi il tuo endpoint in Payload URL e scegli application/json come content type così il body arriva come JSON semplice.
Inserisci una stringa casuale lunga in Secret e conserva lo stesso valore nelle variabili d'ambiente del tuo server.
In Which events would you like to trigger this webhook, scegli solo l'evento push oppure seleziona i singoli eventi, spunta Active e salva.
GitHub invia subito un evento ping; controllalo in Recent Deliveries per confermare che il tuo server ha risposto.
Rispondi in fretta. Restituisci uno stato 2xx in un attimo e fai il lavoro lento dopo in un job in background, perché una risposta più lenta di 10 secondi conta come fallimento.
Calcola la firma sui byte grezzi del body, prima di qualsiasi parsing JSON. Fare il parsing e serializzare di nuovo cambia i byte e la verifica fallisce.
Confronta le firme con una funzione a tempo costante come crypto.timingSafeEqual, mai con un semplice confronto ==.
Usa X-GitHub-Delivery, un ID univoco per ogni consegna, per saltare i duplicati quando reinvii a mano.
Iscriviti solo agli eventi che gestisci. Meno eventi significano meno richieste al tuo server e meno cose da proteggere.
Domande frequenti
GitHub riprova i webhook falliti?
No. La documentazione di GitHub afferma che non reinvia automaticamente le consegne fallite. Puoi reinviarne una a mano da Recent Deliveries per le consegne degli ultimi 3 giorni.
Cos'è l'header X-Hub-Signature-256?
Viene inviato quando il webhook ha un secret. GitHub prende il body della richiesta, calcola un HMAC con SHA-256 usando il tuo secret come chiave e invia il risultato esadecimale preceduto da sha256=. Il tuo server ripete il calcolo e confronta.
Quali eventi può ricevere un webhook?
Molti, tra cui push, pull_request, issues, release e workflow_run. L'header X-GitHub-Event indica l'evento che ha attivato ogni consegna, e ping arriva quando crei l'hook la prima volta.
Posso testare un webhook senza un server pubblico?
Il tuo endpoint deve essere raggiungibile da internet, perché GitHub ci invia le richieste. Per lavorare in locale, usa uno strumento di tunneling che dia al tuo computer un URL pubblico temporaneo, poi usalo come Payload URL.
Webhook o polling dell'API?
Un webhook ti invia ogni cambiamento quando avviene; il polling significa interrogare l'API a intervalli regolari. I webhook usano meno richieste e arrivano prima, e questo conta perché le chiamate API rientrano nei rate limit.
Cosa arriva con ogni consegna
Ogni consegna è una POST con header che la descrivono: X-GitHub-Event indica l'evento, X-GitHub-Delivery è un ID univoco, X-GitHub-Hook-ID identifica il webhook e lo User-Agent inizia sempre con GitHub-Hookshot/.
Il body è il payload dell'evento. Per un push elenca i commit e il riferimento del branch, così uno script di deploy può ignorare i push sui branch diversi da quello che compila.
Verificare il tuo codice con i valori di test di GitHub
GitHub pubblica un input noto così puoi dimostrare che il tuo codice è corretto prima di andare live: il secret It's a Secret to Everybody e il payload Hello, World! devono produrre una firma che inizia con 757107ea.
Il verificatore di questa pagina è precompilato con questi valori. Se il tuo server ottiene lo stesso risultato da essi, il tuo codice di verifica è corretto.
Questa route Express legge il body grezzo, calcola l'HMAC con il tuo secret e lo confronta a tempo costante prima di fidarsi del payload.
express.raw conserva esattamente i byte firmati da GitHub. Il secret arriva da una variabile d'ambiente, mai dal codice.
Header delle consegne
Header presenti in ogni consegna di un webhook GitHub
Header
Cosa contiene
X-GitHub-Event
Il nome dell'evento, come push o issues
X-GitHub-Delivery
Un ID univoco (GUID) per questa consegna
X-GitHub-Hook-ID
L'ID del webhook che l'ha inviata
X-Hub-Signature-256
sha256= più l'HMAC del body, solo quando è impostato un secret
User-Agent
Inizia sempre con GitHub-Hookshot/
Verificatore della firma del webhook
Scrivi un secret e il body grezzo di una richiesta per vedere il valore X-Hub-Signature-256 che GitHub invierebbe. Funziona nel tuo browser con la Web Crypto API; nulla viene caricato.
Secret del webhook
Body grezzo della richiesta
Header della firma ricevuto (facoltativo)
sha256=...
Firma calcolata
Corrisponde: la firma di questa consegna è valida per quel secret e quel body.
Non corrisponde: il secret, i byte del body o l'header sono diversi.
Carica i valori di test di GitHub
Con i valori di test di GitHub il risultato dovrebbe essere uguale a: