Verifying signed webhooks
Headers, signature scheme and a verification example for outgoing webhooks.
Updated
Headers
X-UptimeGuard-Event (incident_opened, incident_resolved, tls_expiring, test), X-UptimeGuard-Delivery (unique id for deduplication), X-UptimeGuard-Timestamp (Unix seconds) and X-UptimeGuard-Signature (v1=<hex>).
Signature
HMAC-SHA256 with your channel's signing secret over the string "<timestamp>.<raw body>". Reject requests older than five minutes and compare signatures in constant time.
Node.js example
import { createHmac, timingSafeEqual } from "node:crypto";
export function verify(rawBody, headers, secret) {
const ts = headers["x-uptimeguard-timestamp"];
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
const expected = "v1=" + createHmac("sha256", secret).update(ts + "." + rawBody).digest("hex");
const given = headers["x-uptimeguard-signature"] ?? "";
return expected.length === given.length && timingSafeEqual(Buffer.from(expected), Buffer.from(given));
}Destinations
Webhook URLs must be public https endpoints; they pass the same destination policy as monitors.