From 5884d6cb303d2303ffd75a489635a2346c73eedf Mon Sep 17 00:00:00 2001 From: bponders12-cell Date: Tue, 1 Sep 2026 16:57:41 -0400 Subject: [PATCH] Harden Firestore ownership rules for cloud architecture --- firestore.rules | 56 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/firestore.rules b/firestore.rules index ea027c9..2c23029 100644 --- a/firestore.rules +++ b/firestore.rules @@ -1,20 +1,54 @@ rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { - - // User Profile Documents + function signedIn() { + return request.auth != null; + } + + function ownsUser(userId) { + return signedIn() && request.auth.uid == userId; + } + + // Every user-owned document is isolated by the Firebase UID. Cloudflare R2 + // is protected separately by the Worker using the same Firebase ID token. match /users/{userId} { - allow read, write: if request.auth != null && request.auth.uid == userId; - - // Ride Summaries and Metadata - match /rides/{remoteRideId} { - allow read, write: if request.auth != null && request.auth.uid == userId; - - // Discrete Events & Performance Benchmarks Subcollections - match /{allSubcollections=**} { - allow read, write: if request.auth != null && request.auth.uid == userId; + allow read, write: if ownsUser(userId); + + match /rides/{rideId} { + allow read, write: if ownsUser(userId); + match /events/{eventId} { + allow read, write: if ownsUser(userId); + } + match /performance/{runId} { + allow read, write: if ownsUser(userId); } } + + match /motorcycles/{motorcycleId} { + allow read, write: if ownsUser(userId); + } + + match /trips/{tripId} { + allow read, write: if ownsUser(userId); + } + + match /events/{eventId} { + allow read, write: if ownsUser(userId); + } + + match /friends/{friendId} { + allow read, write: if ownsUser(userId); + } + } + + // Future public/group collections must be added with explicit field-level + // authorization. Do not use a global recursive wildcard here. + match /groupRides/{groupRideId} { + allow read, write: if false; + } + + match /{document=**} { + allow read, write: if false; } } }