Documentation
Verifying webhook signatures
Every outbound webhook from Veyra carries a Veyragate-Signature header. Verify it before trusting the payload — code samples in 7 languages below.
import crypto from "node:crypto";
const TOLERANCE_SECONDS = 300;
export function verifyVeyragateSignature(
rawBody: string,
header: string | null | undefined,
secret: string,
now = Math.floor(Date.now() / 1000),
): boolean {
if (!header) return false;
const parts = Object.fromEntries(
header.split(",").map((p) => p.trim().split("=", 2) as [string, string]),
);
const t = parseInt(parts.t, 10);
const v1 = parts.v1;
if (!t || !v1) return false;
if (Math.abs(now - t) > TOLERANCE_SECONDS) return false;
const expected = crypto
.createHmac("sha256", secret)
.update(`${t}.${rawBody}`)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected, "utf8"),
Buffer.from(v1, "utf8"),
);
}Each snippet enforces a 5-minute timestamp tolerance, parses the
t= and v1= fields from the Veyragate-Signature header, and uses constant-time comparison to defeat timing attacks.