๐ Webhook Listener: HMAC Verification Guide
Secure your civic endpoints with HMAC SHA256 verification and audit-grade secrets…
To ensure incoming webhook requests are authentic and untampered, the listener uses HMAC SHA256 verification with a shared secret (WEBHOOK_SECRET or GITHUB_WEBHOOK_SECRET).
HMAC verification is your first line of defense against spoofed or malicious webhook traffic.
๐งญ Step-by-Step Setup
- Generate a Secure Secret
Use OpenSSL or any cryptographic tool:
Example output:openssl rand -hex 32civic-rotator-override-9f3a7c2e1b6d4a8f3c1e2a7d9b5f6c3e - Set Environment Variables
In.envor Vercel dashboard:WEBHOOK_SECRET=civic-rotator-override-9f3a7c2e1b6d4a8f3c1e2a7d9b5f6c3e GITHUB_WEBHOOK_SECRET=your-github-secret - Reference in Listener Code
const secret = process.env.WEBHOOK_SECRET;
๐งช Example: HMAC Verification in api/webhook-listener.js
import crypto from 'crypto'; export default async function handler(req, res) { const signature = req.headers['x-signature'] || ''; const rawBody = JSON.stringify(req.body); const secret = process.env.WEBHOOK_SECRET; const hmac = crypto.createHmac('sha256', secret).update(rawBody).digest('hex'); const isValid = crypto.timingSafeEqual(Buffer.from(hmac), Buffer.from(signature)); if (!isValid) { return res.status(401).json({ error: 'Invalid signature' }); } res.status(200).json({ status: 'Webhook verified', received: req.body }); } ⚠️ Common Issues & Fixes
| Issue | Cause / Fix |
|---|---|
| Invalid signature | Signature header missing or incorrect secret used |
| crypto.timingSafeEqual fails | Buffer mismatch—ensure both values are hex strings of equal length |
| undefined process.env.SECRET | Environment variable not set or misnamed in Vercel |
| rawBody is empty | Use middleware to capture raw body before parsing |
๐งฉ GitHub-Specific Notes:
Use the
Use the
x-hub-signature-256 header and compute HMAC using: crypto.createHmac('sha256', secret).update(rawBody).digest('hex'); Strip the sha256= prefix before comparing.
No comments:
Post a Comment