Elegant Tech
Guide · Firebase

Firebase Security Rules checklist

Before launch, 1 question matters more than the rest: can user B see user A's data? In a Firebase app the answer lives in your Cloud Firestore Security Rules. This checklist covers the rules that leak, the rules that hold, a 30 second self test and how to keep them tested, based on the Firebase docs as of 9 November 2026.

Why the Firebase API key is not the problem

Every Firebase web app ships a config object with an API key, and founders often panic when they find it in the browser. Firebase states that API keys for Firebase services only identify your project and app. They do not control access to your data, so they are OK to include in code.

Access to Cloud Firestore, Realtime Database and Cloud Storage data is enforced by Firebase Security Rules, and access to covered APIs by Firebase App Check. Hiding the key protects nothing. Writing the rules protects everything.

One exception is new. Firebase warns never to add the Gemini Developer API, listed as Generative Language API, to the allowlist of a public API key. If your app calls Gemini from the browser, check that key in the Google Cloud console today.

The 4 rule patterns that leak data

  • Test mode left on. When you create a Firestore database you choose test mode or production mode. Firebase says test mode allows anyone to read and overwrite your data. Many AI generated apps were started in test mode and never moved on.
  • allow read, write: if true. Open access. Firebase warns that anyone who guesses your project ID can then steal, modify or delete the data. Search every rules file for if true.
  • request.auth != null and nothing else. This only checks that someone is logged in. Any user who creates an account can read and write every document in that collection, which is exactly how user B ends up seeing user A's records.
  • Email domain checks without email_verified. A rule that trusts request.auth.email ending in your domain can be passed by anyone who signs up with that address. Add request.auth.email_verified to the condition.

What a safe rule looks like

Tie every read and delete to the owner of the stored document: request.auth.uid == resource.data.author_uid. For create, compare against the incoming document instead: request.auth.uid == request.resource.data.author_uid.

Updates need both checks. The user must own the current document and the new version, so nobody can hand a record to someone else or take one over by rewriting the owner field.

Roles are possible with a get() on a users document, for example checking that role equals Writer. Firebase notes that each get() or exists() in a rule is billed as a normal document read, so keep role lookups to the paths that need them.

Remember that rules are not filters. Firebase evaluates a query against everything it could return, and if any of it is off limits the whole request fails. Your app queries must include the same owner condition your rules check.

What rules do not cover

  • Server code. The Firebase Admin SDK, Cloud Functions and the server client libraries bypass Security Rules completely. Every function that reads or writes user data has to check the caller itself.
  • Cloud Storage. Files have their own Security Rules. Locking Firestore does not lock uploads, invoices or profile photos.
  • Abuse of your backend. Rules decide which users can reach which data. App Check decides which apps can call your backend at all, and it is what stops scripts that copy your config and hammer your API.

The 30 second self test

  1. Create 2 test accounts, user A and user B, and give user A a record such as an order, a note or a project.
  2. Log in as user A and copy the document id from the URL or from the network request in developer tools.
  3. Log out, log in as user B and open the same URL, or replay the request with user A's id.
  4. If user B can read, change or delete that record, fix the rule for that collection before anything else ships.

Keep it tested with the emulator

A manual test proves the rules are safe today. A test in CI keeps them safe after the next prompt rewrites the data model. Firebase points to the Cloud Firestore emulator for this, and only the @firebase/rules-unit-testing library can mock auth in Security Rules.

Create a test environment with initializeTestEnvironment, act as user A with authenticatedContext and as a logged out visitor with unauthenticatedContext, then use assertSucceeds and assertFails to prove each read and write does what you expect. Seed data with withSecurityRulesDisabled and reset between tests with clearFirestore.

Write 1 test per collection that holds user data, run the suite against the emulator on every pull request, and a change that opens a collection fails before it reaches production.

The 3 ways to production, and what each costs

  • Harden in place, from $5,000, 2 to 3 weeks. Lock down the database, fix auth, move secrets to the server, add monitoring. The frontend stays as it is. Right when you have under a few hundred users and the product still changes weekly.
  • Rebuild the backend, keep the front, $15,000 to $25,000, 6 to 8 weeks. New API layer, cleaned data model, real permissions, integrations moved server side, tests and CI. Right when users like the product but the plumbing cannot be trusted with money or personal data.
  • Full production rebuild, $25,000 to $35,000, 8 to 10 weeks. Same product decisions on a new stack, UX fixes from real usage, AI features designed in. Right when you are charging money, growing, and know exactly what version 2 should be.

These are our fixed prices for this work, with full IP transfer.

When this checklist is not enough

Security Rules protect data that clients reach through the Firebase SDKs. They do not check Cloud Functions, webhooks or anything running on the Admin SDK, because those bypass rules. If several companies or teams share collections in your app, or money moves through it, test those paths separately with 2 accounts in 2 different teams.

Frequently asked questions

Yes. Firebase states that API keys for Firebase services only identify your project and are OK to include in code. Your data is protected by Security Rules and App Check, not by hiding the key. Never allow the Gemini Developer API on a public key.

Open the Rules tab of Firestore in the Firebase console, or the rules file named in firebase.json. If any match allows read or write if true, or for any logged in user without an ownership check, the database is open.

No. It only checks that the caller is logged in. Anyone can create an account, so every user can reach every document. Compare request.auth.uid with the owner field stored on the document.

No. The Admin SDK and server client libraries bypass Security Rules. Each function must check who is calling and what they are allowed to touch.

Use the @firebase/rules-unit-testing library with the Firestore emulator. Act as different users, assert which reads and writes succeed or fail, and run the tests in CI on every pull request.

Send us a test login. Get the check free.

We test whether one user can see another user's data and send a written report in 48 hours.