---
title: Secret rotation
description: 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:

```ts
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:

1. **Roll the secret with the provider**

    Generate the new secret in the provider's dashboard or API.

2. **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.

3. **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](/docs/providers/standard-webhooks).
