DEV Community

Israr Kundi
Israr Kundi

Posted on Originally published at israr-kundi.web.app

My API Key Is Visible in the Code — How to Fix It

My API key is visible in the code — and if that is what you found, anyone with a copy of your app can see it too. Rotate that key first, then move it off the client, because deleting it from the code alone does not fix the leak.

The problem: your key is sitting in the open

You built the app fast with an AI tool. It works. Then you open the code, or someone else does, and there it is: your API key, sitting in a file anyone can read. It might be in a .env file, in the JavaScript bundle, or right in the source. You did not mean to publish it. The tool put it there so the app could call the API straight from the phone or browser.

In March 2026, VibeWrench scanned 100 apps built with Lovable, Bolt.new, Cursor, and v0.dev. It found 318 vulnerabilities, and 41% of the apps exposed secrets or API keys. One Lovable app had a Supabase service role key sitting in a .env file. With that key, anyone can bypass Row Level Security and read every row in every table. A June 2026 scan by Symbiotic Security looked at 1,072 Supabase-backed vibe-coded apps and found 98% had at least one flaw.

Why it happens

AI builders need the key to call the API, so they drop it into the client code. That is exactly why it leaks. Anything in the client ships with the app. In Flutter, a key passed with --dart-define is baked into the release binary. A .env file added with flutter_dotenv is bundled into the app as an asset. Anyone who pulls the app apart can find both. Some builders even add dangerouslyAllowBrowser: true to the OpenAI SDK to make an error go away. That setting exposes your secret key in client-side code. It is the leak, not the fix.

One thing to get straight: not every key in your code is a leak. A Supabase anon key is public by design. The protection there comes from Row Level Security, not from keeping the key secret. The real danger is secret keys — a service role key, an OpenAI key, a Stripe secret key — sitting where anyone can read them. And when RLS is missing, even the public anon key opens the whole database. A September 2026 UpGuard scan found 16,326 Supabase databases readable by anyone using only the public anon key, because RLS was never turned on.

My API key is visible in the code: the minimum fix

Do these steps in order. The order matters, because the first step is the only one that stops the key from working.

  1. Rotate the key at the provider, first. Make the old key stop working. Once a key has been visible in code or on GitHub, assume someone copied it.

  2. Check usage and billing for calls you did not make. Look at the provider's usage page for calls from countries or times you don't recognise. If someone used your key, you will see it there.

  3. Remove the key from all client code. Search the built bundle and the repo, not just the source file. A key in git history stays readable even after you add .gitignore.

  4. Move the call server-side. Put the key on your own backend, a backend proxy, or an Edge Function, and let the app call that instead. For Supabase, store the secret with the Edge Function secrets and read it inside the function. The browser only calls your function, never the real API.

  5. If the key was ever in git, purge the history — after rotating. Rewrite history with git-filter-repo, force-push, and tell anyone with a clone. Deleting the commit alone does not remove copies others already have.

  6. Stop it happening again. Turn on GitHub push protection, so secrets get blocked before they reach the repo. Keep every .env file in .gitignore. Set a spend cap at the provider, so a future leak cannot run up an open-ended bill.

Hiding the key better is not a fix. Obfuscation makes a key harder to read, not hidden — it is still in the binary and can be pulled out. Do not just delete the key from the code without rotating it. Copies already exist in git history, cached bundles, and anywhere the code was seen.

When to get help instead

Get help if the key could reach real user data, if you are not sure what the key can access, or if the app is already live with users. That means keys like a Stripe secret key or a Supabase service role key, not a publishable key. Check in the provider dashboard what the key can read and write before you decide what to rotate. The same goes if the leak is spread across git history and old builds — that cleanup is easy to get wrong, so get help with it.

If this is your app, contact me through https://israr-kundi.web.app

Top comments (0)