In this guide 6 sections
Before launch, replace every test mode rule with rules written per role. Close the storage buckets, switch on App Check and keep admin keys on the server. Run rule tests in the deploy pipeline. Then try each collection as a stranger, a customer and a staff member.
Remove the test mode rules first
Firebase projects often start with a rule that lets anyone read and write until a set date. It feels harmless on a laptop. Then the date passes, someone extends it, and the live Firestore database sits open to the internet.
Open the rules files and search for the line allow read, write: if true. Realtime Database keeps its rules in a separate file. Storage has its own as well. One forgotten file is enough to leak a customer list.
- The Firestore rules file named in firebase.json
- The Realtime Database rules file
- Storage rules for every bucket
- Any rule that mentions an expiry date
- Emulator rules accidentally copied into production
Write rules per role, not per screen
A staff app and a customer app usually share one project. Put the role on the user’s token as a custom claim, set from a trusted server. Rules then read request.auth.token.role instead of trusting a field the user can edit.
Watch the role field stored in a user document. If a customer can write to their own profile, they can write admin into it. Split profile fields the user may change from fields only the server may set.
Write each rule for one action. Separate get from list, and create from update from delete. A rule that allows list lets a user download a whole collection, not just their own order.
- Customers read only documents where ownerId matches their uid
- Staff read by branch or depot
- Deletes limited to managers
- Field checks on update, so a status cannot jump to paid
- Required fields and types checked on create
Close storage and keep keys on the server
Storage buckets hold invoices, ID scans and delivery photos. A path rule that lets any signed in user read still exposes every file to every customer. Tie the path to the owner’s uid or to a role claim.
Admin SDK keys are different. The service account JSON bypasses all rules. It belongs in the server’s secret store, never in the app bundle, a public repository or a shared chat. Rotate it if it ever left the server.
Turn on App Check so requests come from your real app and not from a script using your public config. Treat it as a second lock. It does not replace rules.
- Service account JSON kept out of the repository
- App Check enforced for Firestore and Storage
- API key restricted by app and by API
- Short lived signed URLs for downloads
Test the rules before every deploy
Run the Firebase emulator in the pipeline and use the rules unit testing library. Write at least three cases per collection: a stranger is refused, a customer sees only their own record and a staff member sees the branch.
Test the failures, not just the successes. A test proving a customer can read their order says little. A test proving they cannot read another customer’s order is the one that catches a mistake.
Deploy rules from the pipeline, not from someone’s laptop. You then get a history of who changed what and a reviewed pull request before the change goes live.
Do a last pass as an attacker
The day before launch, sign up as an ordinary customer and open the browser developer tools. Copy the project config from the bundle. Try to list the users collection, read a neighbour’s order and upload a file to a staff path.
Check the Authentication tab too. Disable the sign in methods you do not use. Anonymous sign in left on by accident gives every visitor a valid uid, and many rules treat that as a logged in user.
Write the results on one page and keep it with the release notes. Then put a rules review in the calendar for each quarter before you close the launch ticket.
Firebase launch sheet
A one page sheet. Rows list each Firestore collection, Realtime Database path and storage bucket. Columns show who may read, who may create, update and delete, the test that proves it and the person who signed it off. A bottom block records the App Check status, the service account rotation date and the sign in methods switched off.
Open a blank worksheet to printQuestions owners ask
Is test mode safe for a short demo?
Only when the project holds no real data and the expiry date is close. Move to proper rules before any customer or staff record goes in. Many leaks come from a demo project that quietly became the live one.
Do security rules protect against the Admin SDK?
No. Admin SDK calls bypass the rules entirely. That is why the service account key must stay on your server, and why server code needs its own check on who is asking.
What does App Check stop?
It confirms a request comes from your genuine app build. That stops casual scripts that copy your public config. It does not replace rules, because a real app can still send a bad request.
How often should rules be reviewed?
Review them whenever a role, collection or screen is added, and at least once a quarter. Rules drift as features grow. Old exceptions tend to stay long after anyone remembers why.
