Firebase API key exposed: is it a secret, and when is it a problem?

An exposed Firebase API key is expected: the apiKey in your Firebase config only identifies your project, and Google's documentation says it is safe to ship in client code. Your data is protected by Firebase Security Rules and App Check, not by hiding the key. It becomes a real problem when the same key can call paid Google APIs such as Gemini or Maps.

The team behind Keybrum's attacksUpdated 15 min read

In short

  • The apiKey in your Firebase config is public by design. Every visitor's browser downloads it, and Firebase's documentation says it is fine in code and in checked-in config files.
  • Security Rules decide who reads and writes Firestore, Realtime Database and Storage. A rule that only checks request.auth != null lets in anyone who signs up, and with a sign-in method open, anyone can sign up with your public key.
  • Since May 2024, keys Firebase creates are restricted to Firebase APIs. Unrestricted keys it had created earlier were limited to Firebase APIs plus every API the project had enabled at the time, and keys you created yourself were not touched.
  • A Google key whose allowlist includes the Generative Language API is a public Gemini credential. Truffle Security found 2,863 live Google keys that could call Gemini in public web pages crawled in November 2025.
  • Check each key under APIs & Services > Credentials: Firebase APIs only, no Generative Language API, and an application restriction for your site or app.
On this page

Is an exposed Firebase API key a problem?

Usually not. The apiKey in your Firebase config is meant to be public. Firebase's documentation describes these keys as public by design: they only identify your Firebase project and app to Google's servers, and the docs say they are fine to include in code or in checked-in config files. Who can read and write your data is decided elsewhere: by Firebase Security Rules, by App Check and, for server access, by Google Cloud IAM permissions.

You could not hide it anyway. A Firebase web app runs the SDK in the browser, so the config object (apiKey, projectId, storageBucket and the rest) ends up in the JavaScript every visitor downloads. Mobile apps carry the same kind of key in google-services.json on Android and GoogleService-Info.plist on iOS. Moving it into an environment variable with a NEXT_PUBLIC_ or VITE_ prefix changes nothing: those prefixes exist to copy the value into the browser bundle.

The key tells Google which project a request belongs to, so the request counts against that project's quota and billing. Firebase's FAQ states that none of the Firebase-related APIs use the key as authorization. That is the opposite of an OpenAI or Stripe secret key, which opens the account to whoever holds it. Those keys are covered in API keys exposed in the frontend.

API keys for Firebase services are not used to control access to backend resources; that can only be done with Firebase Security Rules (to control which end users can access resources) and Firebase App Check (to control which apps can access resources).
Firebase documentation, Learn about and manage API keys for Firebase

What actually protects your Firebase data

Three layers do the job the key does not do, and each one fails in its own way.

LayerThe question it answersWhen it is missing or too loose
Security RulesMay this user read or write this Firestore document, Realtime Database path or Storage file?Anyone holding your config reads, changes or deletes the data from a script, without your app
App CheckDoes this request come from your real app on a genuine device?Scripts call your Firebase backends directly, including paid AI calls through Firebase AI Logic
API key restrictionsWhich Google APIs may this key call, and from which websites or apps?An unrestricted key can call every API enabled in the project, paid ones included
Firebase Authentication sits underneath the rules: it tells them who the user is. On its own, it limits nothing.

Rules carry most of the weight. Firebase's guide to insecure rules warns that with open rules, "anyone who guesses your project ID can steal, modify, or delete the data". Nobody has to guess: the project ID sits next to the API key in your config. The Firebase security rules guide has rules to paste for the common cases.

What a stranger can do with your Firebase config

Your config gives anyone the same starting point your app has. What they reach after that depends on your rules and settings:

With your config, a stranger can try toIt works whenWhat stops it
Read Firestore collections through the REST APIA read rule is if true, or only checks request.auth != nullRules that compare request.auth.uid with the owner of the document
Write, overwrite or delete documentsA write rule is open, or accepts any signed-in userOwner checks on every write
Read the whole Realtime DatabaseThe root has ".read": trueRules per path, with auth.uid === $uid on private data
List and download Cloud Storage filesStorage rules allow reads to everyoneRules that keep each user in their own folder
Create accounts and sign inSign-up is open in Firebase AuthenticationNothing, by design. Rules must treat a fresh account as a stranger
Call Gemini through Firebase AI LogicThe project uses AI Logic without App Check enforcedApp Check enforcement, which Firebase says is required for AI Logic starting 2 November 2026
Call other Google APIs on your billThe key is unrestricted, or its allowlist includes those APIsAPI restrictions: Firebase APIs only on this key

The sign-up row explains why allow read: if request.auth != null leaks. Firebase's docs confirm that anyone holding your key can make authentication requests against your project, so anyone can get an account, and that rule lets every account in. Firebase's insecure-rules guide flags the pattern, and we see it often in generated Firebase apps. It is the Firebase version of an IDOR vulnerability.

The last row has nothing to do with Firebase itself, and it is where an exposed key starts costing money.

When an exposed Google API key is a real problem

Firebase keys, Maps keys and Gemini keys created as standard keys all look alike: a string that starts with AIza, like the example in Google Cloud's documentation. The format says nothing about what a key can do. Its API restrictions do. Google Cloud's documentation is blunt: unrestricted API keys are insecure, and a key without API restrictions can be used with every API that accepts Google Cloud keys.

The Gemini case

In February 2026, Truffle Security showed what that means in practice. Enabling the Gemini API (listed as the Generative Language API) on a Google Cloud project silently gave the project's existing unrestricted keys access to it, with no warning, including keys already sitting in public web pages. In the November 2025 Common Crawl archive, they found 2,863 live Google API keys that could call Gemini. With one of those keys, a stranger could read files and cached content uploaded through the Gemini API, and run models on the owner's bill.

Google has since closed the default path. The Gemini API now rejects requests from unrestricted standard keys, has blocked long-dormant unrestricted keys since 7 May 2026, and since 28 May 2026 creates every new Google AI Studio key as an auth key restricted to Gemini. One door stays open: Google's key page says standard keys with explicit restrictions continue to work, so a key whose allowlist includes the Generative Language API can still call Gemini. If that key is your Firebase key, it is a public Gemini credential. Google also says the Gemini API is moving from standard keys to auth keys, so check its Gemini API key page for the current rules.

Firebase's documentation says the same in plain terms: never include the Gemini Developer API in the allowlist of a publicly accessible key, and keep the Gemini API key out of your code and config files. To call Gemini from a browser app, go through Firebase AI Logic with App Check enforced, or through your own server. An AI route on your server that anyone can call has the same billing problem, so check that it requires a signed-in user.

Maps and other paid APIs

Maps keys are made to sit in web pages, and they are billable. Firebase's docs ask for a separate key for APIs such as Places, restricted to those APIs, instead of reusing the Firebase key. Restrict it to your websites too. A website (HTTP referrer) restriction stops other sites from using your key in a browser, but a script outside a browser can send any referrer it likes, which is why Truffle calls these controls bypassable. App Check now also covers the Maps JavaScript API and Places API (New).

KeyHow you recognise itWhere it belongsWhat it must never have
Firebase web keyBrowser key (auto created by Firebase) in the Credentials pageYour frontendThe Generative Language API, or any non-Firebase API
Firebase mobile keysAndroid key or iOS key (auto created by Firebase)Your mobile appSame as the web key
Maps or Places keyA key you createdYour frontend, with a website restrictionAny API beyond the Maps APIs it serves
Gemini keyGemini API Key or Gemini Developer API key (auto created by Firebase)Your server onlyA place in client code or config files
Service account keyA JSON file with a private_key fieldYour server onlyAny public exposure: it is a real credential
Names as they appear in Google Cloud console under APIs & Services > Credentials, per Firebase's documentation.

How to check your Firebase API key and rules

Six checks. The first five happen in the consoles and change nothing. The last one asks your own project what a stranger gets.

  1. 1

    Find every key in the project

    In Google Cloud console, open APIs & Services > Credentials for your Firebase project. Firebase's own keys are named Browser key, Android key and iOS key, each followed by "(auto created by Firebase)". Any other key was created by you, a teammate or a tool. To see which key a Firebase app uses, open Project settings > General in the Firebase console and pick the app under Your apps, or run firebase apps:sdkconfig WEB YOUR_APP_ID.

  2. 2

    Read each key's API restrictions

    Open the key. If Don't restrict key is selected, it can call every API enabled in the project. A Firebase key should list only the Firebase-related APIs your app uses, for example Identity Toolkit API and Token Service API for Authentication, and never the Generative Language API. Firebase's documentation has the full table.

  3. 3

    See which paid APIs are enabled

    Open APIs & Services > Enabled APIs & services. If the Generative Language API, a Maps API or any other billable API is on, make sure no public key allows it, apart from a separate Maps key restricted to Maps. If the Generative Language API is not enabled, the Gemini problem does not apply to that project.

  4. 4

    Check the application restriction

    On the same key page, an application restriction limits where the key can be used: websites (HTTP referrers) for a web app, package name and SHA-1 fingerprint for Android, bundle ID for iOS. Try a new restriction on a test app and test key first: Firebase warns against changing a production key's restrictions untested.

  5. 5

    Read your rules

    In the Firebase console, open the rules of Firestore, Realtime Database and Storage. Look for if true, ".read": true, and any rule on private data that only checks request.auth != null. The Firebase rules checker flags these patterns for you.

  6. 6

    Ask your project what a stranger gets

    Run the requests below against your own project, first with no account. Then create a throwaway test user with the sign-up request and repeat the reads with that user's idToken: that is the case most rules forget.

bash
# Firestore: can anyone read the users collection?
curl "https://firestore.googleapis.com/v1/projects/YOUR_PROJECT_ID/databases/(default)/documents/users?pageSize=1"

# Realtime Database: can anyone list the top-level keys?
curl "YOUR_DATABASE_URL/.json?shallow=true"

# Create a throwaway test user (only works if email sign-in is on)
curl -X POST "https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"a-long-test-password","returnSecureToken":true}'

# Repeat the reads as that user, with the idToken from the answer
curl -H "Authorization: Bearer ID_TOKEN" "https://firestore.googleapis.com/v1/projects/YOUR_PROJECT_ID/databases/(default)/documents/users?pageSize=1"
curl "YOUR_DATABASE_URL/.json?shallow=true&auth=ID_TOKEN"

# Your Firebase key: can it call Gemini? (this only lists models, it runs none)
curl "https://generativelanguage.googleapis.com/v1beta/models?key=YOUR_API_KEY"
Run these against your own project only, and delete the test user afterwards in Firebase Authentication. YOUR_DATABASE_URL is the databaseURL in your config. Documents or JSON data in the answer mean that caller can read it, an empty {} means the collection is empty or named differently, and a permission denied error means the rules held. On the last request, a list of models means the key can call Gemini. An error there only clears Gemini: an unrestricted key is now refused by the Gemini API too, so step 2 still decides.

How to fix it: restrict the key, then fix the rules

1. Restrict the Firebase key to Firebase APIs

In APIs & Services > Credentials, open the key, choose Restrict key under API restrictions, and keep only the Firebase APIs your app calls. Remove the Generative Language API and anything else that is not Firebase. Then add the application restriction that fits the platform. Change the production key last, once the same settings worked on a test key.

2. Give every other Google API its own key

Create a separate key for Maps or Places, restricted to those APIs and to your websites. Call Gemini from a server function with a key that never reaches a client, or from the app through Firebase AI Logic with App Check enforced. Separate keys also let you replace one without breaking Firebase, which is one of the reasons Firebase recommends them.

3. Replace open rules with owner checks

This is the fix that protects the data. The first rule below lets any signed-in user, so anyone, read and write every profile. The second ties each document to its owner:

javascript
// Leaks: any account passes, including one a stranger just created
match /users/{userId} {
  allow read, write: if request.auth != null;
}

// Holds: each user reads and writes only their own document
match /users/{userId} {
  allow read, write: if request.auth != null && request.auth.uid == userId;
}
Firestore rules, inside match /databases/{database}/documents. For public content, open reads with owner-only writes is a valid pattern.

4. Turn on App Check, then enforce it

Register your app with App Check: reCAPTCHA Enterprise on the web, Play Integrity on Android, App Attest or DeviceCheck on Apple platforms. Watch the metrics before you enforce: once enforcement is on, every request without a valid attestation is rejected, including those from old app versions that never send one. App Check covers Firestore, Realtime Database, Cloud Storage, callable Cloud Functions, Firebase AI Logic and, in preview, Authentication. It checks the app, not the user, so it does not replace owner checks in your rules.

5. Slow down sign-up abuse

If you use password sign-in, Firebase suggests lowering the default quota of the identitytoolkit.googleapis.com endpoints to match your normal traffic, so a copied key cannot drive a brute force attack at volume. Raise it again if your app suddenly grows, or real users will hit sign-in errors.

When to replace the key

Replacing a Firebase key does nothing for open rules: the new key ships in your next build, just as public. Replace it when a key that could reach Gemini or another paid API was public. Create a new key with the right restrictions, move your apps to it, then delete the old one. A deleted key stops working for every app still using it, including mobile versions already installed. Firebase's FAQ calls deletion permanent, while Google Cloud's documentation lets you restore a deleted key within 30 days: plan as if you cannot. If a service account key leaked, follow what to do when an API key leaks: that one is an emergency.

Traps people miss after restricting the key

  • Keys from before May 2024. That month, Firebase restricted its existing unrestricted keys to the Firebase APIs plus every API the project had enabled at the time. An old project that used Maps or Gemini then can still have those APIs on its public key.
  • Keys you created yourself. Firebase's automatic restrictions only touched keys it provisioned. A key made by hand for a test, or by a tool through the API Keys REST API, which creates unrestricted keys unless told otherwise, keeps whatever it had.
  • APIs enabled later. An unrestricted key gains every API you enable afterwards, with no warning. A restricted key does not, which is the point of restricting it.
  • A referrer restriction as the only lock. It keeps other websites from using your key in a browser. A script can send any referrer.
  • Staging pointing at production. When you use separate Firebase projects per environment, Firebase's docs say each build must use its own project's keys, so a staging build never talks to production data.
  • Secrets in Remote Config. Firebase's docs say not to store confidential data in Remote Config: users can read any parameter their app instance fetches.
  • Secrets stored in readable documents. A config or settings collection holding an OpenAI or Stripe key turns one loose rule into a key leak. Keep those keys in your server environment, not in Firestore.

How Keybrum attacks a Firebase app

Keybrum only attacks apps whose owner proved ownership. It finds the Firebase config in your JavaScript, then, with no account and again as a freshly signed-up account, tries to read common Firestore collections such as users, orders and messages. It tests whether the rules accept writes with a request built to fail on an impossible precondition, so nothing is changed. It reads the Realtime Database root, lists the Storage bucket, looks for API keys stored in readable documents, and checks whether your Firebase key can call Gemini by listing models, which runs none.

Every finding comes with the request that worked. Your coding agent reads the findings and the fixes through Keybrum's MCP server, and Keybrum attacks again after the fix, and on every deploy with a plan.

Firebase API key checklist

  • The apiKey in your config is a Firebase-provisioned key, used only for Firebase services.
  • Its API restrictions list only the Firebase APIs your app uses, with no Generative Language API.
  • It has an application restriction: your websites, your Android package and SHA-1, or your iOS bundle ID.
  • No key in the project is set to Don't restrict key.
  • Maps, Places and any other paid Google API use their own restricted keys.
  • The Gemini key lives on a server, or Gemini is called through AI Logic with App Check enforced.
  • No Firestore, Realtime Database or Storage rule opens private data to everyone.
  • No rule treats request.auth != null as enough for private data.
  • App Check is enforced on the products your app uses, after a monitoring period.
  • If you use password sign-in, the Identity Toolkit quota matches your real traffic.
  • Staging and production use separate Firebase projects and keys.

A checklist tells you what your settings say. It cannot show what a stranger actually reaches, signed out and then signed in as someone else.

Questions

Is the Firebase API key secret?

No. It identifies your Firebase project and app, and Firebase's documentation says it is safe to include in code and config files when it is restricted to Firebase services. Your data is protected by Security Rules and App Check. Gemini API keys and service account keys are different: those are secrets.

Is it safe to put the Firebase API key in frontend code or a public repository?

For the Firebase-provisioned key, yes: it ends up in your frontend bundle either way, and Firebase calls it fine in checked-in config files. Before you rely on that, check that its API restrictions list only Firebase APIs. Any other Google key in the same repository needs its own review.

Can someone run up my bill with my Firebase API key?

Two ways exist. Open rules let a stranger read and write your database, and Firestore reads are billed. A key allowed to call paid Google APIs, such as Gemini or Maps, lets them spend on those. Rules and App Check handle the first, API restrictions handle the second.

I got an email from Google Cloud about a publicly accessible API key. What should I do?

Find the key it names under APIs & Services > Credentials. If it is your Firebase key, used only for Firebase services and restricted to Firebase APIs with no Generative Language API, Firebase says it is fine to keep in your code. If it is any other key, restrict it or replace it.

Does App Check replace Firebase security rules?

No. App Check checks that a request comes from your real app on a genuine device. Rules check which user may touch which data. Any user of your real app is a stranger to everyone else's data, so private data still needs owner checks in the rules.

Is an exposed Google Maps API key a problem?

It is expected in a web page, but it is billable. Restrict it to the Maps APIs it uses and to your websites, and keep it separate from your Firebase key. App Check now supports the Maps JavaScript API and Places API (New) for a stronger check than the referrer.

Should I rotate my Firebase API key after it was exposed?

Only if it could call paid APIs such as Gemini. A new Firebase key is just as public as the old one, so rotating does nothing about open rules. When you do replace a key, ship the new one before deleting the old: deletion breaks every app still using it, and Google Cloud only lets you restore a deleted key within 30 days.

Sources

  1. 1.Learn about and manage API keys for Firebase, Firebase Documentation
  2. 2.Avoid insecure rules, Firebase Documentation
  3. 3.Firebase App Check, Firebase Documentation
  4. 4.Production checklist for using Firebase AI Logic, Firebase Documentation
  5. 5.Manage API keys, Google Cloud Documentation
  6. 6.Firebase Remote Config, Firebase Documentation
  7. 7.Using Gemini API keys, Google AI Studio
  8. 8.Google API Keys Weren't Secrets. But then Gemini Changed the Rules., Truffle Security
  9. 9.Google Fixes the Gemini API Key Privilege Escalation Issue, Truffle Security
  10. 10.Millions of user records exposed by 900+ sites via Firebase, The Register

Your app is public. So are its mistakes.

Check what any attacker can already see in it, free, in ten seconds. The full attack, with proof and fixes: €49 once, or €29 a month on a plan.

or continue with Google or GitHub