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

EventWhat we do
installationUpsert the RepoIntegration row; on deleted/suspend, soft-remove it.
installation_repositoriesSync the repo list on the integration.
pushIf 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_alertUpsert 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