Webhook verifier plugin · listing tai42/webhook-verifier-github
Install
Permissions
Provides
github
Webhook verifier — Verify a GitHub webhook delivery’s X-Hub-Signature-256 HMAC before dispatch.
Registers the github webhook verifier. It authenticates an inbound delivery’s
X-Hub-Signature-256 HMAC-SHA256, computed over the exact raw request body and keyed
by the webhook’s shared secret. Bind it to a hook topic to close that topic’s door
against unsigned deliveries.
Bind it to a topic
A verifier is bound per hook topic. The binding names the environment variable that
holds the signing secret through config.secret_env — the verifier looks that
variable up at verify time, so the secret itself never lives in the manifest:
Set the same secret you configured on the GitHub webhook in that variable on every
process that receives deliveries:
The variable name is yours to choose — pick a distinct name per topic when one
deployment verifies several GitHub webhooks with different secrets.
Replay window
GitHub sends no signed timestamp, so replay is defended by remembering each delivery’s
X-GitHub-Delivery id in a seen-set. config takes an optional replay_window_seconds
(a positive int, default 86400 — one day) setting how long an id is remembered:
A delivery whose id was already seen within that window is refused as a replay. A manual
redelivery of the same event carries the same id and is the correct idempotent no-op.
Behaviour
- Fails closed. A missing
secret_env key, a missing environment variable, an
empty secret, a missing X-GitHub-Delivery header, or a non-positive / non-int
replay_window_seconds raises loudly rather than degrading to an unauthenticated
door. A malformed or mismatched signature is an ordinary verification failure.
- Replay-deduped. Each delivery’s
X-GitHub-Delivery id is remembered in a
seen-set for replay_window_seconds (default one day); a replay within the window is
refused and nothing re-dispatches.
- POST only. The signature covers the raw body, so a door binding this verifier
rejects GET.
- The comparison is constant-time, and the
sha256= digest must be exactly 64 hex
characters.
See also