ShipWatchFree scan

Google API key exposed in your frontend: is it a leak, and how do you lock it down?

You opened DevTools on your live app, or a scanner flagged it, and there it is: a string starting with AIza sitting in your JavaScript. Maybe Lovable, Bolt, Cursor or Google AI Studio put it there for a map, for Firebase sign-in, or for Gemini.

Short answer: it depends on what the key is allowed to do. Firebase web config keys and Google Maps JavaScript keys are meant to sit in the browser, but only if they're restricted. A key that can call Gemini (the Generative Language API) must never be in frontend code. An unrestricted key in the browser is a leak.

All Google API keys look alike (AIza + 35 characters), so you can't tell from the string which kind you have. Here's how to tell, and how to fix each case.

Step 1: Find every Google key your live app ships

Do this on the deployed site, not in your editor. What matters is what visitors download.

  1. Open your live app in Chrome, logged out.
  2. DevTools → Network → filter JS → reload.
  3. Press Ctrl+Shift+F (Cmd+Option+F on Mac) and search AIza.
  4. Note each distinct key and which file it's in.

Then search your project for where it comes from. In Vite apps (Lovable, Bolt) anything named VITE_... is bundled into the browser. In Next.js it's anything named NEXT_PUBLIC_.... A VITE_GEMINI_API_KEY or NEXT_PUBLIC_GOOGLE_AI_KEY is a red flag by name alone. (More on this: Vite env variables exposed, NEXT_PUBLIC_ variables exposed.)

Step 2: Find out what each key can do

Open Google Cloud console → APIs & Services → Credentials and select the project. For each key you found:

What you findPublic by design?What to do
Firebase browser key, API list holds only Firebase APIs, no Generative Language APIYes. Firebase says these keys "do not need to be treated as secrets" when set up this wayKeep it. Make sure Firebase Security Rules and App Check protect your data. The key doesn't.
Maps JavaScript API key with a Websites restriction (your domain) and an API list holding only the Maps APIs you useYes, that's how Maps JS is meant to workKeep it. Add quotas. Use separate keys per app.
Any key set to Don't restrict keyNoRestrict it now (Step 3). If it has been public for a while, check usage, then rotate.
Any key whose API list includes Generative Language API (Gemini)No, neverTreat it as leaked: create a new server-side key, switch the app, then disable the old one (Step 4).
A Maps web service key (Geocoding, Places, Routes called directly from the browser)No. Google says web service keys "are not expected to be publicly exposed"Move those calls behind a server or proxy, and give the server key an IP restriction.

Why Gemini changed the rules

For years Google told developers that Maps and Firebase keys weren't secrets. In February 2026, Truffle Security reported (Google API keys weren't secrets, but then Gemini changed the rules) that when the Gemini API is enabled on a project, existing unrestricted keys in that project, including old Maps keys sitting in public HTML, could call Gemini too. That opened uploaded files and cached content, and billed the owner for usage.

Google has since tightened things. As of today (checked Oct 22, 2026), the Gemini API docs say:

That helps, but it doesn't make a Gemini-capable key safe in a browser. A key that's restricted to Gemini still works for anyone who copies it. Google's rule is unchanged: "Never expose keys client-side in production."

Google AI Studio apps

Per Google's docs, AI Studio's Build mode now keeps GEMINI_API_KEY as a server-side secret. Apps built before May 14, 2026 are upgraded to the server-side setup the next time you change their Gemini features. If you exported or deployed an older AI Studio app elsewhere, check its bundle (Step 1). An older client-side setup may still be shipping the key.

Step 3: Lock down keys that are meant to be public

In APIs & Services → Credentials → (your key):

  1. Application restrictions → Websites. Add your production domain, e.g. https://yourapp.com. Add https://*.yourapp.com only if you use subdomains. Remember preview URLs (*.lovable.app, *.vercel.app) if you need them, and remove them when you don't.
  2. API restrictions → Restrict key. Tick only the APIs this key needs, such as Maps JavaScript API and Places API (New). For a Firebase key, keep only the Firebase APIs Firebase lists. Never tick Generative Language API on a browser key.
  3. Quotas. In the console, lower per-day or per-minute quotas for each API to what your app really uses.
  4. Budget alerts. In Billing → Budgets & alerts, set an alert on the project. These are Google's alerts, and they notify you. They don't stop spending by themselves.
  5. Disable APIs you don't use on the project. Per Google's Maps guidance, a disabled API can't be abused through any key.

Website restrictions stop other websites from using your key in a browser. They're not a lock against someone calling the API directly with a forged header. So the API list matters most: a public key should only be able to do public things.

Step 4: If a Gemini (or other paid) key was public, rotate it

Follow Google's own leak checklist, in this order:

  1. Create a replacement key in Google AI Studio or Cloud console, and keep it server-side only: a Supabase Edge Function secret, a Vercel/Netlify server function, Replit Secrets used by server code, or AI Studio's Secrets panel.
  2. Change the app so the browser calls your endpoint, and your endpoint calls Gemini. Require a signed-in user on that endpoint, and rate-limit it.
  3. Deploy, then confirm the old key is gone from the live bundle (Step 1 again).
  4. Disable, then delete, the old key in Cloud console once the new one works.
  5. Check usage and billing in Cloud console for activity you don't recognize.

Deleting the key from your code doesn't un-leak it. Old deploys, caches and git history still have it. Revoking it at Google is what kills it. Full order of operations: Rotate a leaked API key.

Fix prompt for Lovable, Bolt or Cursor

My app calls the Gemini API from the browser using a key in a VITE_ / NEXT_PUBLIC_ variable. Move every Gemini call into a server-side function (Supabase Edge Function / API route). Read the key from a server secret named GEMINI_API_KEY, never from a client env var. The browser should call my function, which checks the user is signed in, then calls Gemini. Remove the old client env var and every reference to it. Show me the diff and list each file that still contains "AIza" after the change.

For a Maps or Firebase key, you usually don't need code changes, just the console restrictions in Step 3.

What the free ShipWatch scan checks here (and what it doesn't)

So a flagged AIza key isn't automatically an emergency. It's a prompt to do Step 2 in the console. A clean scan isn't a guarantee either.

Run the free scan on your live app → (only scan apps you own)

Checked against Google's documentation (Firebase API keys, API keys are open secrets) on Oct 22, 2026. Google changes key behavior often (the Gemini key changes rolled out through 2026), so recheck the linked docs before relying on any date here.

FAQ

Is a Google Maps API key in my frontend a leak?
Not by itself. The Maps JavaScript API is designed to run with the key in the page. It becomes a problem when the key is unrestricted, can call APIs beyond Maps, or isn't limited to your website. Restrict it (Step 3) and set quotas.
Is my Firebase apiKey a secret?
Per Firebase's docs, no, as long as it's used only for Firebase services, restricted to Firebase APIs, and doesn't include the Generative Language API. Your data is protected by Firebase Security Rules and App Check, not by hiding the key.
Can I call Gemini directly from the browser if I restrict the key to my domain?
Google's guidance is no: "Never expose keys client-side in production." Use a backend proxy, or Firebase AI Logic with App Check, which Google describes as calling Gemini without embedding a raw key.
Will a scanner tell me if my key is restricted?
Not an outside-in one like ShipWatch. Restrictions live in your Google Cloud project, which no outside scanner can see. Check them in APIs & Services → Credentials.
Google emailed me about a "publicly accessible Google API key". What now?
Firebase's docs cover this: if it's your Firebase browser key, restricted to Firebase APIs and without Generative Language API, it can stay public. Any other key in that email should be restricted, or rotated if it can reach paid APIs.
Do I need to rotate a Maps key that was unrestricted?
Google's Maps guidance is to restrict first, and rotate only if you see unauthorized use you can't stop with restrictions. A key that can call Gemini or other paid AI APIs should be rotated.

Scan your app free in 30 seconds

Paste your live URL for a plain-English report with fix prompts. If you keep shipping, weekly monitoring re-checks it: Solo $19/mo or Pro $49/mo.

Scan my app free