Safeguard
Developer Tools•

How do you rotate a webhook signing secret without dropping events?

Accept two signing secrets during a short overlap so in flight webhooks still verify. Steps, what to check, and the pitfalls of cutting over at once.

Safeguard Security Team
3 min read

Accept both the old and new signing secret for a short overlap, then remove the old one. If the sender supports it, ask for a delayed expiry. Verifying against two secrets means webhooks signed just before the switch still pass, and nothing is dropped.

What a signing secret does

A webhook endpoint is a public URL. Anyone can post to it. The sender signs each request with a shared secret, and your server recomputes the signature to check the request is real. Without that check, an attacker could trigger orders or account changes with fake events.

Why a hard cutover loses events

Webhook providers usually retry failed deliveries, and events can be in flight when you change the secret. If you replace the secret at once, deliveries signed with the old one fail verification until retried, and some may fail for good. A short overlap avoids the gap.

Stripe's documentation shows the pattern. When you roll an endpoint secret, you can expire the current secret immediately or delay its expiry for up to 24 hours, during which multiple secrets are active and a signature is generated for each. Other providers may behave differently, so check yours.

Steps

  1. Check provider support. Does it allow two active secrets, or a delayed expiry?
  2. Make the new secret in the provider's console or API.
  3. Update your verifier to try each configured secret and accept if any match.
  4. Deploy and confirm that new deliveries verify with the new secret.
  5. Retire the old secret at the provider after the overlap.
  6. Remove the old value from your configuration.
  7. Watch failure rates for a day.
def verify(payload, header, secrets):
    for s in secrets:
        if signature_matches(payload, header, s):
            return True
    return False

The helper signature_matches stands for your provider's verification call.

Keep verification safe

Stripe's documentation also gives rules worth following with any provider: verify against the raw request body, because changing it breaks the signature; compare signatures in constant time; and reject events whose timestamp is too old to resist replay. Its libraries default to a five minute tolerance, and it warns that a tolerance of zero disables the recency check.

If the secret leaked

Do not wait for the overlap. Expire the old secret immediately, accept the brief failures, and rely on the provider's retry or manual resend features to recover events. Stripe describes automatic retries for up to three days in live mode and manual resends for a limited period. Then review what the leaked secret could have been used to forge, such as events your app trusted. See our rotation and leak response steps.

Quick check

How long should the overlap be?

As short as your slowest deploy plus a margin. A few hours is common, and some providers cap it, such as 24 hours in the example above.

Do I need to rotate webhook secrets on a schedule?

Periodic rotation is a common recommendation, including by Stripe, as well as rotation on suspected compromise. Pick a schedule you will actually follow.

Safeguard can scan your repository for signing secrets committed in code, and you can try a free scan.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.