A webhook endpoint is an externally reachable input boundary. A plausible JSON body is not proof that the provider sent it, and a valid signature does not necessarily prove that it is new. Separate transport protection, payload authentication and replay handling in both the design and its tests.
Verify the provider's actual signing scheme
Use HTTPS and the provider's documented signature algorithm. Retain the raw request body for signature verification before parsing or normalizing it. Store the secret in an approved secret system and avoid printing it in logs. If verification fails or the required header is missing, reject the input without applying its requested effect.
GitHub's webhook validation guide documents an HMAC SHA-256 signature in X-Hub-Signature-256 and recommends a secure comparison rather than ordinary equality. This is a concrete reference implementation boundary. Other providers may sign timestamps, selected headers or a different canonical string, so do not transfer the GitHub recipe unchanged.
Treat freshness and identity separately
GitHub's webhook best practices recommend using X-GitHub-Delivery to identify deliveries and note that a requested redelivery retains the original delivery ID. Keep a deduplication record scoped to the relevant subscription or installation. Redelivery should repair processing, not create a second ticket or change.
A body-only signature does not authenticate arbitrary delivery headers. An attacker replaying captured signed bytes with a changed unsigned delivery ID can evade ID-only deduplication. An unsigned timestamp is likewise not evidence of freshness. Treat delivery-ID guidance as one control with this trust boundary, not a cryptographic replay guarantee. Do not invent a GitHub signed-timestamp header. Where a provider signs a timestamp, validate it according to the provider's documented tolerance and canonicalization rules. Where it does not, delivery identity and controlled deduplication are important but have limits: an event replayed after identity retention expires may no longer be recognizable. Set and document retention with that risk in mind.
Compare two replay situations
Suppose the original GitHub delivery has a valid body signature and an already-processed delivery ID. A requested redelivery retains that ID, allowing the receiver to find its recorded state and avoid repeating the effect. Now suppose captured signed body bytes arrive with a different unsigned delivery ID. Body verification can still succeed because that header is outside the signed body; ID-only deduplication is not sufficient cryptographic proof of freshness. These are hypothetical reasoning cases, not executed attacks or provider deliveries.
For a cooperating sender whose documented scheme authenticates an event identity and timestamp together with the payload, test tampering, genuinely signed expired timestamps, future timestamps outside the allowed tolerance and repeated identities. Do not invent such a scheme for a provider that does not offer it. No custom envelope, signing key or replay test is supplied here. Exact-body fingerprints may help investigate repeats, but identical payloads can also represent distinct legitimate events; define business identity and acceptance rules rather than indiscriminately discarding all equal bodies.
Limit the consequence of an accepted event
After verification, validate event type, action, schema and tenant mapping. Bind the trusted subscription to the intended tenant rather than accepting an arbitrary tenant ID from the body. Queue accepted work with a stable identity and keep configuration changes behind their normal approval boundary. An authenticated webhook can report an event without being authorized to change DNS.
Record verification outcome, delivery identity, received time and a safe evidence reference while minimizing payload retention. Stop processing when tenant association or signature status is ambiguous. Recovery should replay a retained verified event through the same guarded path, not bypass validation to clear a queue. This guide does not verify an EmailAuth webhook integration or any real provider delivery.