GitHub webhooks — alert on HMAC signature mismatch
A webhook receiver accepts GitHub events. If signature validation starts failing (someone rotated the secret in one place) — deploys silently break.
Recipe
// /opt/webhook-receiver/index.js
const crypto = require('crypto');
const express = require('express');
const app = express();
const SECRET = process.env.GITHUB_WEBHOOK_SECRET;
const ALERT_URL = process.env.ALERT_URL; // your enterno heartbeat or Slack
let mismatchCount = 0;
app.post('/github', express.raw({ type: 'application/json' }), async (req, res) => {
const signature = req.get('X-Hub-Signature-256') || '';
const expected = 'sha256=' +
crypto.createHmac('sha256', SECRET).update(req.body).digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
mismatchCount++;
if (mismatchCount >= 3) { // alert after 3 in a row
await fetch(ALERT_URL, {
method: 'POST',
body: JSON.stringify({
text: `GitHub webhook HMAC mismatch x${mismatchCount} — secret rotated?`,
}),
headers: { 'Content-Type': 'application/json' },
});
}
return res.status(401).end();
}
mismatchCount = 0; // reset on success
res.status(202).end();
});
app.listen(8080);
Same thing in Enterno.io
Wire this endpoint to an Enterno user-webhook — centralized delivery log plus failure-rate alerts without standing up your own service.
Related recipes
Stripe, GitHub, Twilio return X-RateLimit-Remaining in response headers. If the backend does not track the floor, you get a sudden 429 and billing stops.
Site is on the HSTS preload list, but after an nginx refactor the header is gone. In 3 months the domain will be removed from the preload list. Need a daily check.
A name-server misconfig leaks AXFR to the internet — every subdomain, MX, TXT (including SPF/DKIM keys) is visible to attackers. Daily check with alert.