Design an idempotent webhook verifier
Design the receiving side of webhooks the Stripe way: HMAC-SHA256 over the timestamp and the raw body, a tolerance window against replays, constant-time comparison, two active secrets during rotation, and idempotent processing with leased claims so retries and concurrent deliveries do the work exactly once.
01Understand the problem
- Verify HMAC-SHA256 over `timestamp.rawBody` and know why the raw bytes matter
- Use a tolerance window (Stripe's libraries default to 300 s) against replay
- Make processing idempotent with event ids, leased claims and a unique constraint
- Handle retries and out-of-order delivery without corrupting state
- Rotate secrets with two active secrets and multiple
v1signatures
What they probe: what exactly is signed, why a JSON body parser breaks verification, how replays are bounded, what happens when the same event arrives twice at once, and how rotation works without dropping events. Where candidates slip: verifying re-serialised JSON, === on signatures, no timestamp check, marking an event done before the side effect commits, assuming events arrive in order.
A webhook is an HTTP POST a provider sends to your endpoint when something happens (an invoice is paid). Anyone can POST to that URL, so the provider signs each delivery with a shared endpoint secret. Stripe sends a Stripe-Signature header such as t=1492774577,v1=5257a869...: t is a Unix timestamp and v1 is the hex HMAC-SHA256 of the string t + "." + raw body under the secret. Providers deliver at least once and retry failures (Stripe retries for up to three days in live mode), so duplicates are normal.
- Verify the signature over the exact raw body bytes before parsing JSON.
- Reject timestamps more than 300 s from now in either direction.
- Accept a signature from any currently active secret.
- Process each event id at most once to completion; a failure must allow a retry.
- Return 2xx quickly; slow work goes to a queue.
This is an advanced module
Problems: replay & revocation components is part of the Pro pass. 3 more sections — the deep dives, the final design, follow-ups and the test — unlock with it.
Already a cyart.io or studio.cyart.io member? Your pass code is in your Studio account.