My API key is showing on my website — is that bad?

You opened your site's source, or the network tab, and there's an API key sitting in plain sight. First, don't panic — and don't relax either. Whether a visible key is a shrug or an emergency depends entirely on which kind of key it is.
There are two kinds of keys
This is the whole distinction, and getting it right tells you whether to close the tab or move fast:
Public keys are designed to be seen. A Supabase anon key, a Stripe pk_ publishable key, a Google Maps browser key — these are meant to live in the frontend. They're safe because something else does the protecting. Secret keys are the opposite: a Stripe sk_ secret key, a Supabase service_role key, an OpenAI key, a database URL. These grant real power and must never reach the browser.
pk_ is fine. A visible sk_ is an emergency. If you can't tell which you're looking at, treat it as secret until you've confirmed otherwise — the cost of being wrong runs one direction only.If it's a public key
You're probably fine — but "probably" has conditions. A public key is only safe because a second layer restricts what it can do, and that layer has to actually be configured:
- Supabase anon key: safe only if Row Level Security is on with real policies. Without RLS, that public key reads your whole database.
- Maps / browser keys: lock them to your domain with HTTP referrer restrictions and set usage limits, so a copied key can't rack up your bill on someone else's site.
- Stripe publishable key: it can only start payments, not move money — designed for the frontend.
If it's a secret key
Then it's already compromised. Not "could be" — is. Anything in the bundle has been served to every visitor and possibly indexed by bots that scan for exactly this. Deleting it from your code doesn't un-leak it. You have to:
- Rotate it immediately. Revoke the exposed key and issue a new one. The old value is burned.
- Move the new one server-side into an environment variable your frontend can't read.
- Call the service through a backend route so the key does its work on your server and the browser only ever sees the result.
VITE_ or NEXT_PUBLIC_ is deliberately baked into the client bundle. Put a secret behind one of those prefixes and .env won't hide it — you've told the framework to ship it. Secrets get plain, un-prefixed names and stay on the server.Triage yours in one paste
Not sure which kind you've got? This prompt tells you whether to panic and exactly what to do:
I found an API key visible in my website's frontend code / network tab. Help me figure out if it's dangerous and what to do. Here's the key's purpose: <WHAT THE KEY IS FOR>. 1. Tell me whether this specific kind of key is meant to be public (like a Supabase anon key, a Stripe PUBLISHABLE key pk_, a Google Maps browser key) or is a SECRET that must never ship to the browser (like a Stripe SECRET key sk_, a service_role key, an OpenAI key, a database URL, any private API key). 2. If it's a public key: explain what still protects me (e.g. RLS for Supabase, HTTP referrer/domain restrictions for map keys, usage limits) and how to lock those restrictions down so the public key can't be abused. 3. If it's a secret key: tell me it's compromised the moment it's in the bundle, and walk me through (a) ROTATING/revoking it immediately, (b) moving it to a server-side environment variable, and (c) calling the service through a backend route so the browser never sees it. 4. Explain that in Vite/Next.js, any env var prefixed with VITE_ or NEXT_PUBLIC_ is deliberately baked into the client bundle — so a secret must NOT use those prefixes. Be direct about whether I need to panic or not.
This is one of the most common gaps in AI-generated apps — the model wires the key wherever makes the code run. It's part of the broader vibe coding security risks, and for Supabase specifically, the app-securing checklist.
After the fix
Once the key's rotated and moved, the exposure is closed — but a leaked secret often gets used before you notice, so watch for the fallout: a spiking bill, an endpoint behaving strangely, a service that suddenly goes down. Monitoring from outside catches the symptom even when the cause was a key you've already fixed.
Rotate the key, then keep an eye on the fallout.
Join Tell Me When Down free and we'll watch your app from outside — a service that goes down, an endpoint that starts erroring, uptime that drops — so if a leaked key gets abused before you caught it, you hear about the effect in minutes.
spot something wrong or out of date? [email protected] — we'll fix it