Why Firestore security rules will not stop a leaked service-account key
Firestore IAM is database-wide, so one over-broad datastore grant exposes every collection. Security rules govern client SDKs, not a server-side key, so they cannot help here.
When data exfiltration starts, the instinct is to reach for the access-control feature you know. With Firestore, the obvious lever is the wrong one.
How the attack works
An identity holds an over-broad datastore.user or datastore.owner role, or a leaked service-account key carries it. The attacker authenticates from an unfamiliar location and issues RunQuery and Lookup calls that enumerate documents across every collection, far beyond the service’s normal scope. Then comes an ExportDocuments call that pushes the entire database to a Cloud Storage bucket for offline collection, and a final sweep confirms the grant is database-wide rather than collection-scoped. Because Firestore IAM has no per-collection restriction, a single broad grant exposes the whole datastore. The Cloud Audit Logs Data Access entries are the authoritative record of what was read and exported. This maps to T1530, Data from Cloud Storage, and T1537, Transfer Data to Cloud Account.
Why it works
The grant is the breach. A broad datastore role plus a long-lived key means whoever holds that key reads everything, and there is no IAM-layer boundary between collections to slow it down.
How to fix it
Firestore security rules are the trap here: they govern client SDK and mobile-web access, not server-side IAM or the admin API, so they cannot stop a service-account key reading through the API. The real containment is to disable or rotate the key to kill the credential immediately, then scope the datastore IAM grant to least privilege so a recovered key cannot read everything. Durably, replace the broad role with least-privilege grants, eliminate long-lived service-account keys in favor of short-lived credentials or workload identity federation, and alert on export and bulk-read patterns.
Practice it
We built this as a GraphLattice Range scenario so security teams learn why security rules miss server-side IAM and what actually stops the key.