Structuring Cloud Firestore Security Rules Stay organized with collections Save and categorize content based on your preferences.
Cloud Firestore Security Rules allow you to control access to documents andcollections in your database. The flexible rules syntax allows you to createrules that match anything, from all writes to the entire database to operationson a specific document.
This guide describes the basic syntax and structure of security rules. Combinethis syntax withsecurity rules conditions to createcomplete rulesets.
Note: The server client libraries bypass allCloud Firestore Security Rules and instead authenticate throughGoogle Application Default Credentials. If you're using the server client libraries or the REST or RPC APIs, make sure to set upIdentity and Access Management (IAM) forCloud Firestore.Service and database declaration
Cloud Firestore Security Rules always begin with the following declaration:
service cloud.firestore { // The {database} wildcard allows the rules to reference any database, // but these rules are only active on databases where they are explicitly deployed. match /databases/{database}/documents { // ... }}Theservice cloud.firestore declaration scopes the rules toCloud Firestore, preventing conflicts betweenCloud Firestore Security Rules andrules for other products such as Cloud Storage.
Thematch /databases/{database}/documents declaration specifies that rulesshould match anyCloud Firestore database in the project. While a projectcan contain up to 100 databases, only the first database created is designatedas the default.
Cloud Firestore Security Rules are applied separately for each named database in your project.This means that if you create multiple databases, you must manage and deployrules for each one individually.For detailed instructions on deploying your updates, seeDeploy your updates.
Basic read/write rules
Basic rules consist of amatch statement specifying a document path andanallow expression detailing when reading the specified data is allowed:
servicecloud.firestore{match/databases/{database}/documents{//Matchanydocumentinthe'cities'collectionmatch/cities/{city}{allowread:if<condition>;allowwrite:if<condition>;}}}
All match statements should point to documents, not collections. A matchstatement can point to a specific document, as inmatch /cities/SF or use wildcardsto point to any document in the specified path, as inmatch /cities/{city}.
In the example above, the match statement uses the{city} wildcard syntax.This means the rule applies to any document in thecities collection, such as/cities/SF or/cities/NYC. When theallow expressions in the match statement areevaluated, thecity variable will resolve to the city document name,such asSF orNYC.
cities collection; as a result, they also deny access to documents inall other collections.Granular operations
In some situations, it's useful to break downread andwrite into moregranular operations. For example, your app may want to enforce differentconditions on document creation than on document deletion. Or you may want toallow single document reads but deny large queries.
Aread rule can be broken intoget andlist, while awrite rule canbe broken intocreate,update, anddelete:
servicecloud.firestore{match/databases/{database}/documents{//Areadrulecanbedividedintogetandlistrulesmatch/cities/{city}{//Appliestosingledocumentreadrequestsallowget:if<condition>;//Appliestoqueriesandcollectionreadrequestsallowlist:if<condition>;}//Awriterulecanbedividedintocreate,update,anddeleterulesmatch/cities/{city}{//Appliestowritestononexistentdocumentsallowcreate:if<condition>;//Appliestowritestoexistingdocumentsallowupdate:if<condition>;//Appliestodeleteoperationsallowdelete:if<condition>;}}}
Hierarchical data
Data inCloud Firestore is organized into collections of documents, and eachdocument may extend the hierarchy through subcollections. It is important tounderstand how security rules interact with hierarchical data.
Consider the situation where each document in thecities collection contains alandmarks subcollection. Security rules apply only at the matched path, so theaccess controls defined on thecities collection do not apply to thelandmarks subcollection. Instead, write explicit rules to control accessto subcollections:
servicecloud.firestore{ match/databases/{database}/documents{ match/cities/{city}{ allowread,write:if<condition>;//Explicitlydefinerulesforthe'landmarks'subcollection match/landmarks/{landmark}{ allowread,write:if<condition>; } } }}
When nestingmatch statements, the path of the innermatch statement is alwaysrelative to the path of the outermatch statement. The following rulesetsare therefore equivalent:
servicecloud.firestore{ match/databases/{database}/documents{ match/cities/{city}{ match/landmarks/{landmark}{ allowread,write:if<condition>; } } }}
servicecloud.firestore{ match/databases/{database}/documents{ match/cities/{city}/landmarks/{landmark}{ allowread,write:if<condition>; } }}
Recursive wildcards
If you want rules to apply to an arbitrarily deep hierarchy, use therecursive wildcard syntax,{name=**}. For example:
servicecloud.firestore{match/databases/{database}/documents{//Matchesanydocumentinthecitiescollectionaswellasanydocument//inasubcollection.match/cities/{document=**}{allowread,write:if<condition>;}}}When using the recursive wildcard syntax, the wildcard variable will contain theentire matching path segment, even if the document is located in a deeply nestedsubcollection. For example, the rules listed above would matcha document located at/cities/SF/landmarks/coit_tower, and the value ofthedocument variable would beSF/landmarks/coit_tower.
Note, however, that the behavior of recursive wildcards depends on the rulesversion.
Version 1
Security rules use version 1 by default. In version 1, recursive wildcardsmatch one or more path items. They do not match an empty path, somatch /cities/{city}/{document=**} matches documents in subcollections butnot in thecities collection, whereasmatch /cities/{document=**} matchesboth documents in thecities collection and subcollections.
Recursive wildcards must come at the end of a match statement.
Version 2
In version 2 of the security rules, recursive wildcards match zero or more pathitems.match/cities/{city}/{document=**} matches documents in anysubcollections as well as documents in thecities collection.
You must opt-in to version 2 by addingrules_version = '2'; at the top ofyour security rules:
rules_version='2';servicecloud.firestore{match/databases/{database}/documents{//Matchesanydocumentinthecitiescollectionaswellasanydocument//inasubcollection.match/cities/{city}/{document=**}{allowread,write:if<condition>;}}}
You can have at most one recursive wildcard per match statement, but in version2, you can place this wildcard anywhere in the match statement. For example:
rules_version='2';servicecloud.firestore{match/databases/{database}/documents{//Matchesanydocumentinthesongscollectiongroupmatch/{path=**}/songs/{song}{allowread,write:if<condition>;}}}
If you usecollection group queries, you must useversion 2, seesecuring collection group queries.
Overlapping match statements
It's possible for a document to match more than onematch statement. In thecase where multipleallow expressions match a request, the access is allowedifany of the conditions istrue:
servicecloud.firestore{match/databases/{database}/documents{//Matchesanydocumentinthe'cities'collection.match/cities/{city}{allowread,write:iffalse;}//Matchesanydocumentinthe'cities'collectionorsubcollections.match/cities/{document=**}{allowread,write:iftrue;}}}
In the example above, all reads and writes to thecities collection will beallowed because the second rule is alwaystrue, even though the firstrule is alwaysfalse.
Security rule limits
As you work with security rules, note the following limits:
| Limit | Details |
|---|---|
Maximum number ofexists(),get(), andgetAfter() calls per request |
Exceeding either limit results in a permission denied error. Some document access calls may be cached, and cached calls do not count towards the limits. |
Maximum nestedmatch statement depth | 10 |
Maximum path length, in path segments, allowed within a set of nestedmatch statements | 100 |
Maximum number of path capture variables allowed within a set of nestedmatch statements | 20 |
| Maximum function call depth | 20 |
| Maximum number of function arguments | 7 |
Maximum number oflet variable bindings per function | 10 |
| Maximum number of recursive or cyclical function calls | 0 (not permitted) |
| Maximum number of expressions evaluated per request | 1,000 |
| Maximum size of a ruleset | Rulesets must obey two size limits:
|
Next steps
- Writecustom security rules conditions.
- Read thesecurity rules reference.
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2026-02-18 UTC.