Verifying signatures
Each delivery has an Axsync-Signature header: t=timestamp,v1=hmac.
Compute HMAC-SHA256 over timestamp + '.' + raw_body with your webhook secret and compare in constant time. Reject timestamps older than five minutes to prevent replay.
import crypto from 'node:crypto';
export function verify(raw, header, secret) {
const [t, v1] = header.split(',').map(p => p.split('=')[1]);
const mac = crypto.createHmac('sha256', secret).update(`${t}.${raw}`).digest('hex');
return crypto.timingSafeEqual(Buffer.from(mac), Buffer.from(v1)) && Date.now() / 1000 - t < 300;
}import hmac, hashlib, time
def verify(raw: bytes, header: str, secret: str) -> bool:
parts = dict(p.split('=') for p in header.split(','))
mac = hmac.new(secret.encode(), f"{parts['t']}.".encode() + raw, hashlib.sha256).hexdigest()
return hmac.compare_digest(mac, parts['v1']) and time.time() - int(parts['t']) < 300