Validate webhooks
You can use your secret token to secure webhooks with a signature and validate them.
ClaimsSnap and AgentSnap use an HMAC hex digest with the SHA-256 algorithm. It is generated using your webhook subscription's secret and the payload contents. Configure a secret on the subscription to receive signed deliveries.
Be carefulThe signing input is
JSON.stringify(payload, undefined, 2): the parsed JSON payload serialized with two-space indentation. Do not hash the raw HTTP body or sort/rearrange its keys; a different serialization produces a different signature.
The header with signature value is named x-snapr-signature-256.
Example
import { createHmac, timingSafeEqual } from 'node:crypto';
function verifyWebhook(body: unknown, signature: string | undefined, secret: string): boolean {
if (!signature || !/^[a-f0-9]{64}$/i.test(signature)) return false;
const serialized = JSON.stringify(body, undefined, 2);
if (serialized === undefined) return false;
const expected = createHmac('sha256', secret).update(serialized).digest();
const received = Buffer.from(signature, 'hex');
return received.length === expected.length && timingSafeEqual(received, expected);
}
// In your request handler, after parsing the JSON body:
const isValid = verifyWebhook(request.body, request.header('x-snapr-signature-256'), WEBHOOK_SECRET);Reject the request without processing its payload if isValid is false. Signatures authenticate the payload but do not prevent replay; handle duplicate deliveries safely as described in the webhook glossary.
Updated about 1 month ago