Firestore Rules Audit
Answer three questions about a ruleset, with evidence:
- Who can do what? (access analysis)
- Do the expressions work in their operation context? (semantic validity)
- Do the match blocks compose safely? (structural analysis)
Steps
Read the ruleset. Use the project's
firestore.rules, or the deployed ruleset read back through the Firebase Console orfirebase-toolsfor deployed state. Complete when you can list every match block and the operations each allows.Lint. Run
firestore_lint_rules. Complete when every lint finding is either carried into the report or explained away.Access analysis. For each match block, record identity × operation (get/list/create/update/delete) → allow/deny. Flag public writes, public reads on sensitive paths, and create/update/delete without an auth check. Complete when the access matrix has no blank cells.
Semantic checks. Verify each expression against its operation context:
listcannot rely on a single document'sresource.data— a list query must be constrained so it can only return readable documents.createreadsrequest.resource.data; there is noresource.datayet.- Authorization derives from
resource.data(what exists); the writer controlsrequest.resource.data, so validation — not authorization — reads it.
Complete when every
resource.data/request.resource.datause is justified for its operation.Composition checks. Any matching
allowgrants access — permissive wildcards override specific restrictions elsewhere. Flag recursive wildcards ({doc=**}) that bypass sibling rules, undefined function calls, unused functions whose names near-miss a called one, and repeatedget()/exists()calls that multiply per-request cost. Complete when every wildcard's reach is stated.Prove the findings. Back each critical/high finding with
firestore_simulate_rules(vary auth context and operation) or the hosted Rules Test API, reached withpyric verify --engine rules-test-api|both;pyric verify casescan generate the case list from a captured fixture. Complete when each such finding cites a passing simulation/test demonstrating the problem.Report.
## Firestore Rules Audit ### Summary ### Findings (grouped critical → low, each with evidence + fix) ### Positive Observations ### Recommended Fixes
If the user asks for remediation: change the rules, re-lint, then re-run the simulations or tests that exposed each finding and confirm they now deny.
Reference — high-signal patterns
allow write: if trueorallow write: if request.auth != nullon user-owned data — critical or high depending on path sensitivity.- Validation absent on any user-controlled create/update — high.
request.auth.uid == resource.data.ownerIdoncreate— broken (noresourceyet); the intent needsrequest.resource.data.ownerIdplus a uid check.- Role fields writable by the user they empower — privilege escalation.