Webhook Delivery Service · View 13 of 20 · Runtime
Decisions
- HMAC-SHA-256 over timestamp plus the exact raw request body, under a KMS-wrapped per-endpoint secret. Asymmetric signatures are the better answer to a platform-side compromise and are deferred to Phase 3 (ADR-06).
- Two active secrets, both signatures sent, seven-day overlap. Rotation is a data property the consumer migrates through at their own pace, not a coordinated cut-over (ADR-07).
- The secret is displayed exactly once and never again. A secret the console can show is a secret an account takeover can read.
- The platform reads at most a bounded prefix of the response and never parses it for control information. The response body is untrusted input from an untrusted party.
The consumer's half
- Recompute over raw bytes, not over a re-serialised object — the single most common cause of a mismatch, and the reason the canonical string is published rather than described.
- Reject if the timestamp is outside the acceptance window; the timestamp is in the signed material specifically so a captured request cannot be replayed indefinitely.
- A 401 is classified permanent: the platform stops retrying and tells the endpoint's owner rather than hammering a consumer that is correctly refusing it.
Assumptions
- KMS decrypt cached 5 minutes per worker. Secret rotation effective within 60 s p99 — these two numbers are in tension, and the cache TTL is the one that gives.
- A recommended acceptance window of 5 minutes is published rather than enforced; the platform cannot enforce a consumer's clock.