Skip to content
All guides

Is it safe that my Firebase apiKey is public?

By Obscura Security · Updated · Firebase, Firestore, Google Cloud, Lovable, Bolt, Cursor

Short answer

Yes. The apiKey in your Firebase web config identifies your project and is meant to be in your frontend code. It does not grant access to your data. Security Rules and App Check do that. Still restrict the key in Google Cloud, and never publish a service account JSON file or Admin SDK credentials.

Firebase gives you a block of config with an apiKey in it, and that block ends up in your frontend. Almost every other API key must stay private, so it’s fair to worry. For this one, you don’t need to.

Why a public apiKey is normal

The config object Firebase generates for a web app looks like this:

const firebaseConfig = {
  apiKey: "AIza...",
  authDomain: "your-app.firebaseapp.com",
  projectId: "your-app",
  storageBucket: "your-app.firebasestorage.app",
  messagingSenderId: "1234567890",
  appId: "1:1234567890:web:abc123"
};

Google’s Firebase documentation says that, unlike how API keys are usually used, Firebase API keys don’t control access to backend resources. It states plainly that only Firebase Security Rules do. The key identifies your project to Google’s servers. It sits in the same config as projectId and appId, which nobody expects you to hide either.

What stops a stranger from reading your database is the rules attached to Firestore, Realtime Database and Storage. If those rules are open, the key is irrelevant, because anyone can guess your projectId. If they’re tight, the key is harmless. See Firebase Security Rules that are wide open.

Where a Firebase key can still cost you

The key belongs to a Google Cloud project, and a Google Cloud API key can call any API that’s enabled on that project, unless the key is restricted. Firebase projects often get other APIs switched on later: Maps, Places, Vision, or a generative AI API. An unrestricted key in your frontend can call those too, and the bill lands on your project.

Two other points:

  • Account creation. With email and password or anonymous sign-in enabled, the key is enough to create accounts through the Auth API, without going through your app. Your rules should check what a user is allowed to do, not whether they exist.
  • Abuse of your quotas. A copied config can be used from any website or script. App Check exists to cut that off.

Not the same thing: service account keys

A service account JSON file and the Admin SDK credentials are secrets in the full sense. They’re used by servers, and they bypass Security Rules completely. Anyone holding one has admin access to your project’s data.

The file contains "type": "service_account" and a long "private_key". These must never be in frontend code, a public repository, a Lovable or Bolt project that is shared, or a NEXT_PUBLIC_ environment variable. On Google Cloud hosting such as Cloud Functions, you often don’t need a key file at all, because the platform provides credentials.

How to check your own app

  1. Look at the key’s restrictions. In the Google Cloud console, choose the project, then APIs & Services → Credentials. Open the browser key Firebase created for your web app. Note whether it has application restrictions (HTTP referrers) and API restrictions.
  2. See which APIs are enabled. Under APIs & Services → Enabled APIs & services, look for anything beyond Firebase that costs money per call.
  3. Test your rules from the outside with your own key. This asks Firestore for a collection without signing in:
curl "https://firestore.googleapis.com/v1/projects/YOUR_PROJECT_ID/databases/(default)/documents/users?key=YOUR_API_KEY"

A permission-denied response is what you want. If documents come back, your rules are open, and that is the real problem. Only run this against your own project.

  1. Search your code and git history for service account files:
grep -rn "BEGIN PRIVATE KEY\|service_account" . --include="*.json" --include="*.js" --include="*.ts" --include="*.env*"

Also check git log for a file you once committed and later deleted. See secrets committed to GitHub if one turns up.

The fix

1. Keep the apiKey where it is, and lock down the rules

Fix Firestore, Realtime Database and Storage rules first. Nothing else on this page matters if they allow everyone.

2. Restrict the browser key

On the key’s page in APIs & Services → Credentials:

  • Under application restrictions, choose Websites and add your real domains, such as https://yourapp.com/* and your *.web.app and *.firebaseapp.com addresses. Add localhost entries for development if you need them.
  • Under API restrictions, choose Restrict key and select only the APIs your app uses.

Be careful with the API list. Firebase Auth and other services call several Google APIs behind the scenes, for example Identity Toolkit and Token Service. If you cut one that your app depends on, sign-in or other features break. Change one thing at a time and test your app after each change.

If you need a Maps or generative AI key as well, create a separate key for it, with its own restrictions, instead of reusing the Firebase one.

3. Turn on App Check

Register your web app with App Check in the Firebase console, then enforce it for Firestore, Storage and Cloud Functions after you have tested that your own app still works. Monitor mode first shows what would be blocked.

4. Rotate a leaked service account key

If a service account JSON file was ever public, delete that key in the Google Cloud console under IAM & Admin → Service Accounts, on the account’s Keys tab, and create a new one. Then move it into your server’s environment variables.

Mistakes to avoid

  • Hiding the apiKey and leaving the rules open. That solves a problem you didn’t have and keeps the one you do.
  • Assuming a scanner alert means data was stolen. It may only mean your public config was found. Check the rules and key restrictions.
  • Putting an Admin SDK or service account file in client code to “make a permissions error go away”. Fix the rule instead.
  • Reusing the Firebase key for paid APIs. Make a separate, restricted key.

Common questions

A scanner or GitHub alert flagged my Firebase API key as leaked. Do I need to rotate it?
Not as an emergency, because the key is public by design. Check that Security Rules are locked down and that the key is restricted in Google Cloud. If the same Google Cloud project has other paid APIs enabled and the key was unrestricted, restrict it now.
Can someone use my apiKey to read my Firestore database?
Only if your Security Rules allow it. The key lets a client talk to your project, and the rules decide what that client may read or write. With rules that require a signed-in user and check ownership, the key on its own gets an attacker nothing.
Can someone use my apiKey to create accounts in my app?
If a sign-in method like email and password or anonymous sign-in is enabled, anyone with the key can create an account through the Firebase Auth API without using your app. Your rules should not treat 'signed in' as 'trusted'.
What is App Check and do I need it?
App Check makes Firebase services accept requests only from your real app, not from a script that copied your config. It is an extra layer on top of Security Rules, not a replacement. It is worth turning on for Firestore, Storage and Cloud Functions once your rules are solid.
How do I tell a service account key from a web config?
A web config is a small JavaScript object with apiKey, authDomain, projectId and similar fields, and the key starts with AIza. A service account key is a JSON file containing a private_key field and the text 'type': 'service_account'. Only the second one is a secret.

Written by Obscura Security, an Australian practice that checks web apps for problems like this one. If you want a second pair of eyes on yours, email [email protected].