1 min lesson
Signing and verification: trust before you dedup
Take "Signing and verification: trust before you dedup" step by step, then finish with the result that proves it worked.
Step 1 of 2
Signing and verification: trust before you dedupHMAC + timestamp
Before a consumer dedups an event it should know the event is genuine. Providers sign the payload with a shared secret using HMAC and the receiver recomputes the signature to verify it. Include a timestamp in the signed material and reject anything too old or an attacker can capture a valid request and replay it later.
- 1Sender computes
HMAC-SHA256(secret, timestamp + "." + body)and sends it in a header. - 2Receiver recomputes the same HMAC over the raw body it received and compares with a constant-time equality check.
- 3Reject stale timestamps outside a small window (e.g. ±5 minutes) so a captured-and-replayed payload fails even though its signature is valid.
- 4Then verify the signature, then dedup by event id, then process.
When Cursor emits webhooks to customers, the idempotency key you put in the payload is part of the service contract. Customers build their own dedup against it. If you change or drop that key, you break consumers downstream. Treat it like any other API surface: versioned, documented and stable. This is exactly the "clean abstractions and well-defined service contracts" the JD asks an EM to own.
Learn more
Full explanation
Full explanation
The trade-off you'll be pushed onwindow vs cost
- Longer TTL
- Catches duplicates that arrive far apart (a DLQ replay days later). Costs more storage.
- Shorter TTL
- Cheap, but a late duplicate slips through after the key expires.
- How to size it
- TTL ≥ your maximum retry-plus-DLQ-replay horizon. If you can replay a DLQ after 7 days, a 1-hour dedup window is a bug.
The dedup window must outlive the longest path a duplicate can take to reach the consumer.
QYour dedup TTL is 1 hour, but operators can replay the DLQ up to 7 days after an incident. What goes wrong and what's the fix?