Webhooks
Pencheff registers a single webhook endpoint — /webhooks/github — and
subscribes to four event types on the GitHub App. Every payload is verified
with HMAC-SHA256 using the webhook secret you configured; any payload with
a missing or mismatched signature is rejected with 401 Unauthorized.
Events handled
| Event | What we do |
|---|---|
installation | Upsert the RepoIntegration row; on deleted/suspend, soft-remove it. |
installation_repositories | Sync the repo list on the integration. |
push | If the push is to the repo’s default branch and auto_scan_on_push is enabled, queue a new scan pinned to the pushed commit SHA. |
dependabot_alert | Upsert the alert as a RepoFinding on the repo’s latest scan. |
Non-default branch pushes are intentionally ignored to keep noise low.
Verifying locally
GitHub sends X-Hub-Signature-256: sha256=<hex> on every webhook. The
handler computes HMAC-SHA256(body, webhook_secret) and compares both
values using hmac.compare_digest. If you want to replay a payload with
curl, generate the header yourself:
sig=$(openssl dgst -sha256 -hmac "$GITHUB_APP_WEBHOOK_SECRET" -hex \
< payload.json | awk '{print $2}')
curl -X POST http://localhost:8000/webhooks/github \
-H "Content-Type: application/json" \
-H "X-GitHub-Event: push" \
-H "X-Hub-Signature-256: sha256=$sig" \
--data-binary @payload.json