Skip to content

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_body

using HMAC-SHA256 and the endpoint secret.

Verification steps ​

  1. Read Cedius-Signature.
  2. Extract t and v1.
  3. Read the raw request body.
  4. Build timestamp.raw_body.
  5. Compute HMAC-SHA256 with the endpoint secret.
  6. Compare signatures with a timing-safe function.
  7. Reject timestamps outside the replay window.
  8. 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.

Cedius is an illustrative API documentation portfolio project.