Your Firebase Web Config Is Public by Design — Here's What to Actually Secure

Is your Firebase API key safe to expose? Yes — the web config is public by design. Here's what it does, why rotating it is pointless, and what to actually lock down.

Barret8 min read

You opened your app's source code — or maybe a scanner did it for you — and there it was: your Firebase apiKey, sitting in plain text where anyone with a browser can read it. So now you're asking the obvious question: is my Firebase API key safe to have out there in public, or did my AI builder leak the keys to my entire app?

Short answer, and take a breath: it's safe. The Firebase web config — apiKey and all — is designed to be public. It's a name tag, not a password, and rotating it does nothing for your security while risking your live app.

This post explains what that key does, why Google ships it in your frontend on purpose, and — the part that matters — where your real protection comes from. Because there is a Firebase credential that's a true secret, and it isn't this one.

⚡ TL;DR

  • The Firebase web config / apiKey is public by design. It identifies your project so requests reach the right backend; it does not grant access to your data.
  • Rotating it is pointless — it's not a secret, so there's nothing to "un-leak." Doing so only risks breaking your live app.
  • Your real protection is Security Rules, locked Storage rules, and App Check. The one credential you must never ship is the service-account JSON key.

Is the Firebase API key safe to expose? Yes, and here's why

Let's start with the thing that's keeping you up. A Firebase web config looks like a wall of secrets:

const firebaseConfig = {
  apiKey: "AIzaSyD-EXAMPLE-not-a-secret",
  authDomain: "your-app.firebaseapp.com",
  projectId: "your-app",
  storageBucket: "your-app.appspot.com",
  appId: "1:1234567890:web:abc123"
};

It reads like a password. It isn't one. The Firebase apiKey is an identifier, not an authorizer. Its job is to tell Google's servers, "these requests belong to the project called your-app." It does not, on its own, let anyone read a document, download a file, or sign in as anyone.

The analogy that makes it click: the web config is the street address of your house printed on the front of the building. Anyone walking past can read it — that's fine, because the address doesn't open the door. The locks on the doors do. In Firebase, the locks are Security Rules, a completely separate system from the config. So when someone copies your apiKey, they've learned where your project lives, not been handed a key to it. Whether they can reach your data depends entirely on your rules — for them exactly as much as for you.

🐺 Not a real problem

An exposed Firebase web config / apiKey is not a leak — Google built it to be embedded in your frontend. If a scanner flagged it as a critical exposure and told you to rotate it, that scanner is crying wolf. The real question is never "is the key public?" — it's "do my Security Rules and Storage rules actually restrict who can read and write?"

Why does Google ship the API key in the browser on purpose?

This trips people up because every other system has trained you to hide your keys. So why would Google deliberately put one in public?

Because of how Firebase works. In most apps, your browser talks to your server, which checks permissions before touching the database. Firebase skips that middleman: the browser talks straight to Google's services. There's no server of yours in between to hold a secret, so the credential that identifies your project has to live in the browser — there's nowhere else to put it. That's why the public config isn't a mistake Google tolerates; it's a deliberate design choice. Protection was always meant to come from a separate layer Google enforces on every request: Security Rules. Your job isn't to hide the config — it's to make sure the rules are doing their work.

One optional bit of hygiene: in the Google Cloud console you can add API key restrictions (limiting which websites the key works from). It's a reasonable belt-and-suspenders step, but not the thing protecting your data — don't let it distract you from the rules.

So what actually protects your Firebase app?

If the key isn't the lock, here's what is. Three controls do the real work, and an AI builder tends to set up none of them correctly by default.

1. Security Rules — who can read and write your database. A short rulebook Google evaluates on every read and write to Firestore or Realtime Database. The dangerous default an AI tool emits is allow read, write: if true; — "yes to everyone, always." A safe rule ties each document to its owner with request.auth.uid == userId. There are about a dozen ways to get this wrong; we catalog them in Firebase Security Rules: 12 mistakes AI tools make.

2. Locked Storage rules — who can read and write your files. Firebase Storage has its own rulebook, separate from the database. People lock the database, feel safe, and forget the file bucket is wide open — the most damaging Firebase mistake in the wild.

3. App Check — proving requests come from your real app. Even with good rules, anyone can take your public config and call your backend from a script. App Check attaches a verifiable token so Firebase can reject traffic that didn't come from your genuine app — a layer on top of rules, not a replacement.

For the full walkthrough, see the cornerstone: Firebase security for AI-built apps.

The one credential that is a real secret

Now the part to actually pay attention to. There is exactly one Firebase credential that deserves the fear people wrongly aim at the apiKey: the service-account key.

It's a JSON file that grants server-side admin access through the Firebase Admin SDK — the master key. Code using it bypasses Security Rules entirely: read anything, write anything, delete anything, no questions asked. It's meant to live only on a server you control. Never in a browser. Never in a public repository.

It looks like this, and if a file like it is anywhere a user or the public could reach it, treat that as a five-alarm fire:

{
  "type": "service_account",
  "project_id": "your-app",
  "private_key_id": "...",
  "private_key": "-----BEGIN PRIVATE KEY-----\n...REAL SECRET...\n-----END PRIVATE KEY-----\n",
  "client_email": "firebase-adminsdk@your-app.iam.gserviceaccount.com"
}

Hold the contrast in your head, because it's the entire point:

  • The web config / apiKey is public by design. Shipping it is fine; rotating it is pointless.
  • The service-account key is a real secret. Shipping it is an emergency, and rotating it — in the Google Cloud console — is the one case where rotation truly matters.

A scanner that can't tell these two apart will scare you about the harmless one or miss the dangerous one. Telling them apart is the whole job.

The same pattern on Supabase: anon vs service_role

If you've also used Supabase — the default backend for most AI builders — this is the exact same shape. Supabase ships a public anon key meant to live in the browser, exactly like the Firebase web config; it's safe to expose, and the real protection is Row Level Security (RLS), Supabase's version of Security Rules. It also has a secret service_role key that bypasses RLS entirely — the direct equivalent of the Firebase service-account key. Same trap, same fix: don't panic about the public one, never ship the secret one. We put them side by side in service_role vs anon key: which one actually ends your company.

How to check your own app

You can settle this in about five minutes, no code required.

  1. Confirm the key in your frontend is the web config, not a service account. If the object has apiKey, authDomain, projectId, and appId, that's the public web config — it's supposed to be there. Relax.
  2. Search everything for the real secret. Search your project files and any public repo for "type": "service_account" and private_key. If that file is anywhere a user could reach it, treat it as a leak.
  3. Read your Security Rules out loud. Firebase Console → Firestore (or Realtime Database) → Rules. If you see allow read, write: if true; or a "test mode" banner with an expiry date, your data is open right now — and that's what the key panic was distracting you from.
  4. Check Storage rules separately. Console → Storage → Rules. The file bucket has its own rulebook and it's the one people forget.

Not sure if your app has this exact issue?

Run a free, read-only scan of your live app — no install, results in under a minute.

Scan my app free →

What to do (and not do) about the public key

The short version: do not rotate the web config — it's public by design, so there's nothing to un-leak, and rotating it only risks breaking your live app. Instead, point that energy at the rules. Make sure your Security Rules check ownership (request.auth.uid == userId) instead of allow read, write: if true, lock your Storage rules to owners, and get any service-account JSON out of client code and your repo (rotating that if it ever shipped publicly).

If you build with an AI tool, you can paste a prompt like: "My Firebase web config is in my frontend. Confirm that's expected and do not rotate or hide it. Instead, review my Firestore and Storage Security Rules — replace any allow read, write: if true or test-mode rules with rules that require authentication and check that request.auth.uid matches the owner. Then confirm no service-account JSON key is present anywhere in client code."

FAQ

Is it safe for my Firebase API key to be public, and should I rotate it?

It's safe, and no — don't rotate it. The web config, including the apiKey, is designed to be embedded in your frontend and visible to anyone. It identifies your project; it does not grant access to your data, so rotating it protects nothing and only risks breaking your app. The credential where rotation actually matters is the server-side service-account key: if that ever shipped in client code or a public repo, rotate it in the Google Cloud console immediately and audit for misuse.

Can someone steal my data if they have my Firebase config?

Only if your Security Rules let them. With the public config alone, an attacker can learn which project you're on and send requests — but whether those requests return data depends entirely on your rules. With authentication and ownership checks in place, the config is harmless. With allow read, write: if true, the data is open regardless of the key.

What's the difference between the Firebase API key and the service-account key?

The web config apiKey is a public identifier that routes requests to your project; it's meant to ship in the browser. The service-account key is a private JSON file that grants full admin access through the Admin SDK and bypasses all Security Rules — it must live only on a server you control. One is a name tag; the other is the master key.

The bottom line

The Firebase web config is public on purpose, so stop hiding it and stop rotating it. Your data's safety lives in three places — Security Rules, locked Storage, and App Check — plus the rule that the service-account key never leaves your server. An attacker can read your public config in seconds and then probe your rules to see what's actually open; find the open rule or open bucket first, and keep checking, because your AI ships new collections and new gaps every time you add a feature.

Find your gaps before an attacker does.

Is My Site Hackable? scans your deployed app for the exact issues in this article — exposed keys, missing RLS, open buckets — and tells you what's real and what's a false alarm.

Run a free scan →