Prompt
I’m building a product that needs signed webhook verification
Latest observation
Oct 11, 2026
OpenAI APIWeb search: off
Sure — signed webhook verification is a common and important pattern.
At a high level, you want to:
- Receive the raw request body
- Read the signature header sent by the webhook provider
- Recompute the expected signature using your shared secret or public key
- Compare signatures securely
- Reject the request if verification fails
Common verification patterns
1) HMAC signature
The provider sends:
- a payload body
- a timestamp
- a signature header like
X-Signature: sha256=...
You verify by:
- taking the exact raw body
- concatenating/formatting it with the timestamp if required
- computing
HMAC-SHA256(secret, message) - comparing with the header value using constant-time comparison
2) Asymmetric signatures
The provider signs with a private key, and you verify with a public key. This is less common for webhooks, but useful for stronger separation of duties.
Best practices
- Use the raw body exactly as received
- Don’t parse and re-serialize JSON before verification.
- Use constant-time comparison
- Avoid timing attacks.
- Check timestamp freshness
- Prevent replay attacks.
- Store secrets securely
- Rotate them if possible.
- Fail closed
- If verification cannot be completed, reject the webhook.
- Log verification failures carefully
- Don’t leak secrets or full payloads unnecessarily.
Example HMAC flow
Pseudo-logic:
raw_body = request.body_bytes
timestamp = request.headers["X-Webhook-Timestamp"]
signature = request.headers["X-Webhook-Signature"]
message = timestamp + "." + raw_body
expected = HMAC_SHA256(secret, message)
if constant_time_compare(signature, expected):
accept
else:
reject
Things that often go wrong
- Verifying against parsed JSON instead of raw bytes
- Missing/incorrect timestamp handling
- Wrong header name or encoding
- Using a normal string comparison
- Forgetting to handle retries/idempotency
If you want, I can help you design:
- a provider-agnostic webhook signature scheme
- a verification implementation in your language of choice
- or a test plan for signed webhook verification