My Stripe secret key is exposed

Most leaked keys cost you money by being used. This one can move money that's already yours. That's a different kind of urgent, and it changes the order you do things in.

Do this first

  1. Check the prefix. sk_test_ is not an emergency. sk_live_ is. Thirty seconds, below.
  2. Roll it โ€” Stripe Dashboard โ†’ Developers โ†’ API keys โ†’ the โ‹ฏ menu next to the secret key โ†’ Roll key. Choose expire immediately if you can deploy the new one right now.
  3. Then read your Payments, Refunds and Payouts for the whole window the key was public. Rolling stops the future; it does nothing about the past.

1. Which key is it?

Stripe puts the answer in the first few characters, which is genuinely helpful of them.

PrefixWhat it means
pk_live_
pk_test_
Not a leak. The publishable key is designed to sit in your frontend. It can create payment intents and tokenise cards; it can't read your data or move your money. It's in your page source on purpose.
sk_test_
rk_test_
Not an emergency. Test-mode keys only touch test data and fake card numbers. Roll it when convenient โ€” it's untidy, not dangerous.
sk_live_ Emergency. Full API access to your live account. Keep reading.
rk_live_ Depends. A restricted key, limited to the permissions someone chose for it. Open it in the dashboard and read what it can actually do before you panic โ€” it might be read-only on one resource, or it might be nearly as broad as a secret key.
whsec_ Different problem, still real. The webhook signing secret. It can't call the API, but anyone holding it can forge webhook events your server will believe โ€” a fake checkout.session.completed is a free order. Roll it in Developers โ†’ Webhooks โ†’ your endpoint.

2. What a live secret key actually allows

It's worth being specific, because "someone has your Stripe key" covers a wide range of outcomes:

Money can leave. That's the difference between this and a leaked LLM key, and it's why the "check what happened" step is not optional here.

3. Rolling it without taking payments down

Developers โ†’ API keys, then the โ‹ฏ next to your secret key โ†’ Roll key. Stripe offers you an expiry window โ€” 1 hour, 24 hours, or immediately โ€” during which the old key keeps working alongside the new one.

That window exists so you can deploy without an outage, and it is a genuine trade-off:

Don't forget the places that aren't your app: staging, a CI secret, a Zapier or Make connection, a serverless function with its own environment settings, that one cron job on a VPS.

4. Replace it with a restricted key, not another secret key

Nearly every AI-built app uses sk_live_ โ€” full account access โ€” to do about four things: create a checkout session, read a session, handle a webhook, maybe list a customer's subscriptions.

Stripe lets you create a restricted key (rk_live_) with exactly those permissions and nothing else. Developers โ†’ API keys โ†’ Create restricted key, then tick only what your code calls. It's ten minutes of clicking, and it means the next leak โ€” because there's usually a next one โ€” is a much smaller conversation.

Rolling the key fixes today. Downgrading to a restricted key fixes the category. Do both while you're already in the dashboard.

5. Checking what was done with it

Stripe keeps a proper audit trail, which makes this more tractable than most breaches. Cover the full window: from the commit that exposed the key to the moment you rolled it.

If you find anything at all: contact Stripe support and say plainly that a live secret key was exposed and you believe it was used. They deal with this weekly, they can see more than you can, and getting in early matters for how fraudulent charges are handled.

6. Where it usually leaked from

Across a couple of hundred public AI-built apps, live Stripe keys turned up in three recurring places โ€” none of them the payment code itself:

7. Keeping it out next time

Paste this into whatever built the app:

Find every place a Stripe key appears in this repository, including markdown files, scripts, config and environment examples. Any secret key (sk_ or rk_) must be read from process.env on the server only โ€” move any client-side usage into a server route. Confirm the publishable key is the only Stripe key reaching the browser bundle, and that every webhook handler verifies the Stripe signature before trusting the event. List every file you changed.

Check whether there's another one

vibecheck scans your project for exposed keys โ€” live Stripe keys, secrets compiled into frontend bundles, unverified webhook handlers โ€” and explains each one in plain English, with a fix prompt to paste back into your AI coding tool.

Scan my project โ€” free