Verify webhook signatures
A production webhook integration must verify incoming requests.
The illustrative Cedius signature header is:
http
Cedius-Signature: t=1788969600,v1=7ec4...Signing model
The sender signs:
text
timestamp + "." + raw_request_bodyusing HMAC-SHA256 and the endpoint secret.
Verification steps
- Read
Cedius-Signature. - Extract
tandv1. - Read the raw request body.
- Build
timestamp.raw_body. - Compute HMAC-SHA256 with the endpoint secret.
- Compare signatures with a timing-safe function.
- Reject timestamps outside the replay window.
- Process only after verification succeeds.
Node.js example
js
import crypto from "node:crypto";
export function verifyCediusWebhook(rawBody, signatureHeader, secret) {
const parts = Object.fromEntries(
signatureHeader.split(",").map((item) => item.split("="))
);
const timestamp = parts.t;
const received = parts.v1;
if (!timestamp || !received) return false;
const payload = `${timestamp}.${rawBody}`;
const expected = crypto
.createHmac("sha256", secret)
.update(payload)
.digest("hex");
const expectedBuffer = Buffer.from(expected, "hex");
const receivedBuffer = Buffer.from(received, "hex");
if (expectedBuffer.length !== receivedBuffer.length) return false;
return crypto.timingSafeEqual(expectedBuffer, receivedBuffer);
}Verification must use the raw request body.