Webhook Signature Verifier
Verify HMAC-SHA256 webhook signatures with timing-safe comparison at the edge
Accept a raw payload, secret, signature header value, and algorithm. Computes the expected HMAC (Stripe/GitHub sha256= hex style) and returns whether it matches using a timing-safe compare.
Features
- POST /verify - HMAC-SHA256 verification with clear comparison explanation
- Supports prefixed signatures (
sha256=...) and raw hex - Uses Web Crypto at the edge; no external libraries
API Reference
POST /verify
payload string (required) - Raw request body as received.
secret string (required) - Shared signing secret.
signature string (required) - Signature from the webhook header.
algorithm string (optional) - Default sha256.
Example Request
curl -X POST "https://your-worker.workers.dev/verify" \
-H "Content-Type: application/json" \
-d '{"payload":"{\"id\":1}","secret":"whsec_test","signature":"sha256=..."}'Success Response
{
"match": true,
"algorithm": "sha256",
"expectedSignature": "sha256=...",
"providedSignature": "sha256=...",
"explanation": "Timing-safe comparison of 32-byte HMAC digests returned match."
}Error Codes
400-INVALID_BODY,MISSING_FIELD,INVALID_ALGORITHM
Use Cases
- Debug Stripe, GitHub, or Shopify webhook signature mismatches
- Learn timing-safe HMAC verification patterns for Workers
- Validate signing logic before wiring production webhook handlers
Limitations
- HMAC-SHA256 only in this experiment
- Secrets are sent in the request body; use only for debugging, not production traffic
- No replay protection or timestamp validation
Deployment
Configure bindings
See wrangler.json and the experiment README for required bindings.
Test your deployment
See the experiment README for curl examples.
Local Development
cd apps/experiments/webhook-signature-verifier
npm install
npm run devConfiguration
No bindings required beyond the Workers runtime.