SECURITY6 min read

API keys in your front end: how AI-built apps leak secrets

AI assistants often put API keys where the browser can read them. Which keys can be public, how to find the ones that can't, and how to fix a leak properly.

Ask an AI assistant to add AI chat, email or payments to your app and it will usually get it working. Look closely, though, and the key that makes it work may be sitting in your app's browser code, where anyone can copy it. It's one of the most common problems in AI-built apps, and one of the easiest to check.

This guide explains how keys end up in the front end, which ones are fine to be public, how to find the rest, and how to fix a leak properly.

How keys end up in the browser

Many AI-built apps are React projects built with Vite. Vite puts any environment variable whose name starts with VITE_ into the code it sends to the browser, and its documentation says plainly that these variables shouldn't contain sensitive information such as API keys. An assistant that names a key VITE_OPENAI_KEY to make a feature work has published it.

Keys also leak by being pasted straight into source files, committed to the repository, or shared in a chat with an AI tool and copied from there into code.

Which keys are meant to be public

Some keys are designed to be in the browser, because they only identify your account and the real protection lives elsewhere:

  • Supabase publishable or anon key: safe only when Row Level Security protects every table
  • Stripe publishable key (starting pk_)
  • Analytics and map keys that are restricted to your domain

Everything else stays on the server: secret and service_role database keys, Stripe secret keys (starting sk_), AI provider keys, email service keys and anything that can spend money or read private data.

How to find exposed keys

  1. Search your environment files. List every variable with a VITE_ (or NEXT_PUBLIC_) prefix and ask whether it's meant to be public.
  2. Search the code. Look for sk_, secret, service_role, api_key and long random strings.
  3. Check the live site. Open your app, open the browser's developer tools and search the loaded scripts for the same words. This is exactly what an attacker does.
  4. Check the history. Deleting a key from the latest code doesn't remove it from earlier commits. If your repository is on GitHub, its secret scanning can flag known key formats.

How to fix a leak

DO THIS FIRSTRotate the key before you change any code.

Once a key has been public, assume someone has it. Create a new key at the provider and revoke the old one. Moving it out of the front end only protects the new key.

  1. Move the call to the server. The browser asks your own server function, and the server calls the provider with the key.
  2. Store the key in your host's environment settings, never in the code or the repository.
  3. Add limits. Use the narrowest permissions the provider offers, restrict keys to your domain where possible, and set spending limits on AI and email accounts.
  4. Protect the new server function. Check that the user is signed in and allowed to use it, or you've simply moved the open door.

Why this matters when you leave a builder

Platform exports rarely include secrets, so every key has to be set up again on the new host. That's the right moment to move keys out of the front end, rotate anything that was exposed, and put each account in your business's name.

On every migration, AppExit checks for exposed keys, along with data that anyone can read, sign-in and access rules, and outdated packages, before and after the move, and tells you what we find. Please never send us keys or passwords through our forms; we arrange least-privilege access with you separately. Read the five security problems we check for, or start your order.

Sources

Sources checked November 2026. AppExit is not affiliated with any company named. Brand names belong to their owners.

Share this guideLinkedInXReddit
KEEP READING