How do I hide API keys in a vibe-coded app?
Updated 22 October 2026 · 6 min read
Short answer: You can't hide a key in frontend code. Anything named VITE_ or NEXT_PUBLIC_ is copied into the JavaScript every visitor downloads. Put secret keys in your builder's server-side secrets and call the API from a server or edge function. Then rotate any key that was ever public.
Why is my key visible even though it's in .env?
Vite, which most Bolt and Lovable apps use, says variables starting with VITE_ "will be exposed in client-side source code after Vite bundling" and "should not contain sensitive information such as API keys". (Vite docs) Next.js, used by v0, inlines NEXT_PUBLIC_ values into browser JavaScript the same way. (Next.js docs) The .env file isn't the problem. The prefix and where the code runs are.
Which keys are OK in the browser?
- OK: Supabase URL and anon/publishable key (with RLS on), Stripe
pk_keys, analytics IDs. - Never: OpenAI
sk-, Anthropic, Stripesk_live_, Supabaseservice_roleorsb_secret_, Resend, database passwords.
How do I fix it in Bolt?
Bolt has a Secrets tab (database icon → Secrets) that only server functions can read. (Bolt docs)
Remove all OpenAI (or other provider) API calls and keys from the frontend and from any VITE_ variable. Store the key as a secret and create a server function that reads it, checks the caller is signed in, and calls the provider. Call that function from the frontend. Show me every file you changed.
How do I fix it in v0 / Next.js?
Move every call that uses a secret API key into a Next.js route handler under app/api. Read the key from an environment variable without the NEXT_PUBLIC_ prefix. The browser should call /api/... instead. Add a simple rate limit and check the user is signed in.
How do I fix it in Lovable?
My public frontend code contains a secret API key. Move every call that uses it into a server-side function (a Supabase Edge Function or an API route) that reads the key from an environment variable. Make sure the key no longer appears in any file that ships to the browser, then tell me which key to rotate.
I've moved it. Am I done?
No. Rotate the key in the provider's dashboard: anyone who already copied the old one can still use it. Then redeploy and run a free Vibe Check to confirm the key is gone from your live JavaScript.
Related: Supabase key leaks · Pre-launch checklist
Not sure if your app has this problem?
Run a free Vibe Check. It takes about 10 seconds and only reads public pages.
Run free Vibe CheckFAQ
Is it safe to put my OpenAI key in a VITE_ variable?
No. VITE_ variables are bundled into browser JavaScript, so anyone can read the key and spend your credits.
Is the Supabase anon key a secret?
No, it's designed to be public, but only safe with Row Level Security on every table.
Do I need to rotate a key I already removed?
Yes. Removing it from code doesn't stop anyone who already copied it.