GHSA security-advisory webhook
This page is auto-generated from
src/blocklist/webhook.ts. Do not edit by hand — seedocs/dev/docs-auto-sync.md.
Inbound webhook from GitHub — real-time GHSA advisory publish / withdraw.
| Method | Path |
|---|---|
USE | /-/blocklist/webhook/ghsa |
POST | /-/blocklist/webhook/ghsa |
Signature verification
Section titled “Signature verification”Mechanism: HMAC-SHA256 (GitHub webhook convention)
Transport: X-Hub-Signature-256 header (sha256=<hex>)
GitHub-style HMAC-SHA256 of the raw request body, encoded as sha256=<hex>. Constant-time hex comparison against the expected value. Identical scheme to GitHub’s own webhook signature.
Idempotency
Section titled “Idempotency”No explicit dedup gate at the receiver. The downstream action is naturally idempotent (e.g. unbind on an already-unbound row is a no-op).
Retry posture
Section titled “Retry posture”Retry posture is governed by the upstream’s webhook delivery contract. Upwarden responds 2xx on accepted deliveries (including known-no-op events) so the upstream stops retrying; transient failures return 5xx so the upstream re-delivers within its retry budget.
Request body
Section titled “Request body”SecurityAdvisoryEvent
Section titled “SecurityAdvisoryEvent”| Field | Type | Optional |
|---|---|---|
action | "published" | "updated" | "performed" | "withdrawn" | "republished" | no |
security_advisory | GhsaAdvisory | no |
Dispatch tables
Section titled “Dispatch tables”No dispatch tables found in source.
Architecture preamble
Section titled “Architecture preamble”The leading doc-comment block from the source file, reproduced verbatim. This is the canonical narrative explanation of the receiver — the auto-generated sections above are derived from it.
GHSA webhook receiver — #100 (#C1) real-time path.
Turns the existing 15-min delta poll into near-instant: GitHub fires a`security_advisory` event when an advisory is published / updated /withdrawn, we validate the signature and write straight to the blocklist.
Topology: GitHub Webhook → POST /-/blocklist/webhook/ghsa ↓ HMAC-SHA256 signature check ↓ upsertGhsaAdvisory (published / updated / performed) ↓ withdrawGhsaAdvisory (withdrawn) ↓ setBlocklistLastSync("ghsa", now) // freshness signal
The poll cron (k8s/blocklist-fast-sync-cron.yml) stays running as abackstop — if a webhook delivery is dropped (GitHub's at-most-once-ishdelivery is best-effort), the next 15-min sync picks up the miss. Sameholds for the daily full-sync. Defense in depth, not replacement.
Why this matters: the 24h → 30min reduction from the fast-sync pollclosed the bulk of the gap; this closes the long tail. The firstinstall of a freshly-flagged malware no longer waits up to 15 minutesfor the next poll to catch it. The cost is one new endpoint + oneshared secret.