Secret rotation
Pass an array of secrets; any match wins. Rotate with zero missed deliveries.
Every provider option that takes a secret also takes an array of secrets. During verification, any match wins:
stripe({
secret: [process.env.STRIPE_SECRET_NEW!, process.env.STRIPE_SECRET_OLD!],
})
Why this matters
Rotation is not instantaneous on the provider side. Stripe, for example, keeps the previous secret valid for 24 hours after you roll it — deliveries signed with either key arrive interleaved during that window. A single-secret implementation has a 24-hour hole where half your webhooks fail verification.
The safe sequence:
Roll the secret with the provider
Generate the new secret in the provider’s dashboard or API.
Deploy with both secrets
New first, old second. Order doesn’t affect correctness — any match verifies — but listing the current secret first checks it first.
Drop the old secret
Once the provider’s overlap window has passed, deploy again with just the new one.
Rotating signature headers too
Some schemes rotate inside the header instead: Standard Webhooks sends a space-delimited list of versioned candidate signatures, and the SDK checks all of them against all of your secrets. You get both dimensions of rotation for free — see Standard Webhooks.