Home / Errors / Lovable / api-keys-exposed

Lovable API key exposed: secrets visible in your client-side code

Lovable Moderate 30-60 minutes, plus key rotation at each provider security critical Last verified Jul 17, 2026
The fix  Rotate the exposed key at the provider first; removing it from code does not un-leak it. Then move every secret to Lovable Cloud Secrets or Supabase Edge Function secrets and have an edge function proxy the API call, so the browser never sees the key. Anything with a VITE_ prefix is compiled into the public bundle and is already compromised.

Symptoms

  • Third-party keys (OpenAI, Stripe, SendGrid) are visible to anyone who opens DevTools or views the published app's bundled JS
  • You find out the fun way: a key gets abused and the bill spikes, or a scanner flags the site
  • Worst case: the Supabase service_role key, which bypasses RLS entirely, is sitting in frontend code
  • Keys pasted into the Lovable chat persist in chat history that remixers of a public project can read

Why it happens

The AI takes the path of least resistance

Asked to 'integrate the OpenAI API', the AI calls the API directly from the browser with the key inline or in a VITE_-prefixed variable, because that is the shortest route to a working demo.

VITE_ variables are compiled into the public bundle

Anything with a VITE_ prefix ships to every visitor's browser. Lovable's own docs state that secrets in frontend code should be considered compromised.

Nothing errors, so it ships

An exposed key produces no failure signal. The app works, the demo impresses, and the leak sits there until someone abuses it.

How to fix it

  1. Search the code for leaked keysWith GitHub sync on, search the repo for key prefixes: sk-, sk_live_, service_role, and eyJ (JWTs). Anything found under src/ is compromised, full stop. Treat this as an active incident until rotation is done.
  2. Rotate every exposed key immediatelyGo to each provider's dashboard and rotate the key now. Removing a key from code does not un-leak it; it lives on in git history and in Lovable chat history. Honest note: any abuse that happened before rotation already happened, and rotation does not refund the bill.
  3. Move secrets to server-side storageStore secrets in Lovable Cloud > Secrets or as Supabase Edge Function secrets. Never give a secret a VITE_ prefix; the VITE_ prefix is precisely what makes a value client-visible.
  4. Proxy third-party APIs through an edge functionAsk Lovable: 'Create a Supabase Edge Function that proxies my [provider] API calls. Read the key with Deno.env.get() inside the function, and have the frontend call the function using only the anon key.' The browser then never sees the secret.
  5. Never paste secrets into the chat boxKeys pasted into the Lovable chat persist in chat history, and on a public or remixable project, anyone who remixes it can read that history. If you already pasted a key there, rotate that key too.
  6. Know your two Supabase keysThe anon key is safe to ship only if RLS is properly enabled on every table. The service_role key bypasses RLS entirely and must never appear anywhere client-side. If service_role is in your frontend, treat the entire database as exposed and rotate it first.

How to prevent it

  • Store every key in Lovable Cloud > Secrets or edge function secrets from day one, never in code.
  • Never use a VITE_ prefix for anything secret; that prefix means 'publish to every browser'.
  • Never type a secret into the Lovable chat box, especially on public or remixable projects.
  • Periodically search the synced GitHub repo for sk-, sk_live_, service_role, and eyJ.
  • Keep the service_role key strictly server-side; the frontend gets the anon key only.

Tools that actually fix this

Recommended because they address the failure mode above, not because of the payout. Some are affiliate links; see how we choose.

Frequently asked questions

Where should I store API keys in a Lovable app?

Store API keys in Lovable Cloud > Secrets or as Supabase Edge Function secrets, and call third-party APIs through an edge function that reads the key with Deno.env.get(). The frontend should only ever hold the Supabase anon key. Lovable's own docs say any secret that reaches frontend code should be considered compromised.

If I delete an exposed API key from my code, is it safe?

No. Deleting a key from the code does not un-leak it: it persists in git history if the project is synced to GitHub, and in Lovable chat history if it was ever pasted there. The only real fix is rotating the key at the provider and moving the replacement into server-side secret storage.

Why did the AI put my API key in the frontend?

When you ask an AI builder like Lovable to integrate an API, its path of least resistance is calling that API directly from the browser with the key inline or in a VITE_-prefixed variable, and VITE_ variables are compiled into the public bundle. Nothing errors when this happens, so the app works and ships. That silence is the problem: key exposure produces no failure signal until the key is abused.

Is the Supabase service_role key ever safe in client code?

Never. The service_role key bypasses Row Level Security entirely, so anyone who extracts it from your bundle can read and write your whole database. It belongs only in server-side contexts such as edge functions. If it has ever shipped client-side, rotate it immediately and assume the data was accessible in the meantime.

Sources

Related errors

The Vibe Oops briefing

One email when something ships to production that should not have. New incidents, new error guides, no filler.