How the signature works
signing_secretis the secret we gave you for this endpoint.timestampis the value of theX-Pazy-Webhook-Timestampheader, exactly as sent.raw_bodyis the request body bytes exactly as received, before any parsing.- The result is hex-encoded and sent in
X-Pazy-Webhook-Signatureassha256=<64 hex characters>.
Verification steps
1
Read the raw body
Capture the body as a string before your framework parses it. Re-serialized JSON can differ in key order or whitespace, and then the signature won’t match.
2
Check the timestamp
Parse
X-Pazy-Webhook-Timestamp as an integer. If it differs from your current time by more than 5 minutes in either direction, reject the request with 401. This stops an attacker replaying a captured request.3
Recompute the signature
Compute
HMAC-SHA256(secret, timestamp + "." + rawBody) and hex-encode it.4
Compare in constant time
Strip the
sha256= prefix from the header and compare the two values with a timing-safe function. Return 401 on a mismatch.5
Parse and process
Only now parse the JSON and handle the event.