Missing Primitives: Transaction Awareness and Trusted Server Metadata in Security Rules
Firestore Security Rules currently lack two capabilities that force developers to choose between security, performance, and maintainability.
- Lack of Transaction/Batch Awareness Rules cannot verify if a write is part of an atomic batch or transaction. This makes it impossible to enforce multi-document integrity constraints natively.
The Fallout: Developers must either trust the client to perform all parts of an operation (unsafe) or move logic to Cloud Functions. This introduces latency and cold-starts, but more importantly, it fragments security logic. Concise, native rules bolster security because they are easier to audit and are implemented correctly more often than fragmented, multi-layered workarounds.
- No "Middle Ground" for Server-Side Operations Currently, a server must either use the Admin SDK (which results in a full administrative bypass of all rules) or Identity Platform to impersonate a user. There is no way for a server to provide "partial validation" for a request that must still remain failable if it violates standard Rule constraints.
The Fallout: Current limitations incentivize the use of "shared secrets"—checking for specific plain text properties or "magic strings" within the document data to signal that a server has "blessed" the write. This pattern may be adopted because it is more efficient than the alternatives, but it is brittle and mimics security without the actual structural protection of the Rules engine.
Use Case Examples
Relational Integrity (The "Escrow" Logic): A Purchase document must be created if and only if the Product status is simultaneously updated to sold in the same atomic transaction.
External Validation (The "Verified Invite"): A server validates a one-time invite code against a 3rd-party API and "stamps" the request as valid. The Rules then check this stamp alongside request.auth to ensure the user isn't on a blacklist. The server validates the code; the Rules validate the user.
State Synchronization (The "Booking Lock"): A user booking a hotel room must create a Booking doc and update the Room availability timestamp in one batch. Without is_transaction, rules cannot prevent "orphaned" bookings.
Requested Features
request.is_transaction: A boolean allowing rules to reject non-atomic "partial" updates to sensitive multi-document states.
request.auth.token.server_assertions: A way for the Admin SDK to attach non-forgeable, temporary metadata to a user-authed request. This allows the server to act as a co-validator without needing a full administrative bypass.
Appendix: Proposed Rule Syntax Examples
A. Multi-Document Invariants
JavaScript
// Ensure a product status isn't flipped without a corresponding purchase record
match /products/{productId} {
allow update: if request.resource.data.status == 'sold'
&& request.istransaction == true
&& existsAfter(/databases/$(database)/documents/purchases/$(request.auth.uid)$(productId));
}
B. Co-Validation (Failable Requests)
JavaScript
// Server verifies the invite, Rules verify the user identity and blacklist status
match /workspaces/{workspaceId}/members/{memberId} {
allow create: if request.auth.uid == memberId
&& request.auth.token.serverassertions.inviteverified == true
&& !get(/databases/$(database)/documents/blacklist/$(memberId)).exists();
}
Summary: Firestore needs a way to combine user auth with trusted server assertions and transaction visibility. Without these, secure patterns are significantly harder to implement than unsafe ones.