I leaked a Stripe API key: expire it, roll it, check the logs

Short answer: in the Stripe Dashboard, open the API keys page and rotate the exposed key. If it is compromised and you want it dead now, choose Now as the expiration, which deletes the old key; otherwise a grace period (up to 7 days) lets you migrate without downtime. Publishable keys (pk_) are meant to be public; secret and restricted keys are not.

This is the Stripe page for the leaked-key playbook, written from Stripe’s API keys documentation, read on 2026-11-01.

Which key leaked?

Stripe’s docs list the key types. A publishable key (pk_...) is marked “safe to expose” (for Stripe.js, Elements and mobile SDKs) and “can’t perform sensitive operations such as creating charges or reading account data.” A restricted API key (rk_...) has permissions you control and is listed as not safe to expose. Treat a secret key (sk_...) the same way: it carries broad access. Leaking a publishable key is not an incident. Leaking a secret or restricted key is.

Rotate the key (Dashboard)

Stripe lists compromise explicitly as a reason to rotate: “If a secret or restricted API key is compromised, and you need to revoke it to block any potentially malicious API requests that might use the key.” The steps, from the docs:

  1. On the API keys page, click the overflow menu for the key and select Rotate key.
  2. Choose an expiration from the dropdown. “If you choose Now, the old key is deleted. If you specify a time, the remaining time until the key expires displays below the key name.”
  3. Click Rotate API key, copy the new key value (“You can’t retrieve it later”) and add a note with where you saved it.

Two modes, depending on whether anyone is abusing the key:

  • Abuse suspected or the key is public: choose Now. The old key stops working immediately; expect an outage until the new key is deployed.
  • No sign of abuse and you need to avoid downtime: use the grace period. Stripe says that when you rotate in the Dashboard “both the old and new keys work for up to 7 days,” and suggests rolling the new key out to a small subset of servers first, watching logs for errors, and expiring the old key “only after its request volume has been at zero for a few hours or days.” If you need more than seven days, create a new key manually, migrate, then expire the old one.

Expire without replacing

You can also Expire a secret or restricted key directly; “you must create a new one and update any code that uses the expired key,” and code using it “can no longer make API calls.” A publishable key can’t be expired. A request made with an expired key returns an authentication error, which is a handy signal when you’re hunting for forgotten copies.

Check what the key did

Before and after you expire it, look at the key’s request logs (Stripe’s docs point to Workbench request logs and say to check a key’s request logs before expiring it) for requests you don’t recognize: refunds, payouts, customer data reads. Rotating stops future use; it does not undo past actions.

Make the next key less powerful

  • Use restricted keys with only the permissions an integration needs, one per integration.
  • Stripe notes that a restricted key can be tagged as belonging to an autonomous agent, with different governance, if you give a key to an AI system.
  • Keep keys out of source files and chat; store them in a secrets tool and deliver them at runtime (migration guide).

After the provider is fixed: every other copy

Replacing the key at Stripe is half the job. The same value is usually also in other services, a CI variable, a teammate’s .env or another vault. With Dynv you can preview one operation that finds each copy it knows about (including the same value under another name) and replaces them together: pipe the new value in so it never lands in shell history, for example pbpaste | dynv rotate STRIPE_SECRET_KEY --leaked --stdin --dry-run, then run it again with --yes (the plan also suggests copies under other names, which you add with --also SERVICE:KEY). --leaked means “everywhere, no fallback, no stages; the old value stops working now”, which is what you want after a leak. Dynv only knows copies stored in Dynv; search repositories, CI and chat for the old value’s prefix yourself. The generic order of operations, with the evidence on how fast leaked keys are used, is in the 15-minute playbook.

Limits of this page

  • We read Stripe’s own documentation on 2026-11-01 (linked above) and did not exercise Stripe’s console or API for this post. Console layouts and defaults change; follow Stripe’s current instructions where they differ.
  • If the key was in a repository, rotating it is the fix; cleaning Git history is housekeeping (how).
  • If an AI chat or an agent saw the key, see what to do.

Facts last verified . Spotted an error? Tell us.

New here? Start here for the guides in a sensible order.