Receive HTTP POSTs when events happen on your agents. Each payload is signed with HMAC-SHA256 via the X-FyrAgents-Signature header so you can verify authenticity.
HMAC-SHA256 over <timestamp>.<raw body>. Compare in constant time and enforce a 5-minute freshness window to defeat replays.
// Node.js (Express). req.rawBody must be the raw request
// body BEFORE any JSON parsing — wire your body-parser like
// app.use(express.json({ verify: (req, _, buf) => { req.rawBody = buf; }}))
const crypto = require("crypto");
function verify(req, secret) {
const header = req.headers["x-fyragents-signature"] || "";
const parts = Object.fromEntries(
header.split(",").map(p => p.trim().split("="))
);
const t = parts.t, v1 = parts.v1;
if (!t || !v1) return false;
const signedPayload = `${t}.${req.rawBody.toString("utf8")}`;
const expected = crypto
.createHmac("sha256", secret)
.update(signedPayload)
.digest("hex");
// Optional freshness check (5-minute window) to defeat replays.
if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
return crypto.timingSafeEqual(
Buffer.from(v1, "hex"), Buffer.from(expected, "hex"),
);
}