Glossary
Secret Rotation
Replacing a webhook signing secret on a schedule or after a leak — without dropping deliveries — by temporarily accepting signatures from both the old and new secret.
Signing secrets are long-lived shared keys, and anything long-lived eventually leaks — a stack trace, a committed .env, an ex-employee's laptop. Rotation limits the blast radius: rotate on a schedule (every 90 days is a common policy) and immediately on any suspected exposure.
The zero-downtime pattern is dual-secret overlap: generate the new secret at the provider, configure your handler to accept a signature matching *either* secret, then retire the old one once the provider has switched. Stripe supports this natively (roll keeps the old secret valid for up to 24h); GitHub requires you to update the secret and tolerate a brief mismatch window yourself.
A rotation that isn't rehearsed is a rotation that gets skipped. Treat it like a deploy: scripted, reversible, and verified by sending a test event through the new secret before deleting the old one.
Handler accepting either secret during rotation
function verifyWithRotation(body: Buffer, sig: string) {
return (
verify(body, sig, process.env.WEBHOOK_SECRET_CURRENT!) ||
verify(body, sig, process.env.WEBHOOK_SECRET_PREVIOUS!)
);
}How HookSense helps
HookSense stores per-endpoint signing secrets encrypted at rest, and updating one is a single settings change — `verify_signature` immediately checks against the new value, so a rotating secret never requires touching agent code or redeploying a handler.
Get a free webhook URL