Secure Webhook Verification with Signature Rotation
Webhook verification is easy with one static secret and fragile during key rotation. A production-grade design supports overlapping keys and replay defense.
Step 1: store active and previous signing keys
{
"active_key_id": "k2026-03",
"previous_key_id": "k2026-02"
}
Step 2: verify signature against allowed key set
def verify(sig, body, keys):
return any(hmac.compare_digest(sig, sign(body, k)) for k in keys)
Step 3: reject replay with timestamp window + nonce store
if abs(now - ts) > 300: raise ValueError("stale")
if nonce_seen(nonce): raise ValueError("replay")
Pitfall
Flipping to a new secret instantly with no overlap period. Legitimate in-flight requests start failing.