How do you implement role-based access control with Firestore security rules?

Answer

Role-based access control (RBAC) in Firestore uses custom claims and security rules: (1) Set custom claims on the server via Admin SDK: await admin.auth().setCustomUserClaims(uid, { role: "admin" }); (2) Access in rules: function isAdmin() { return request.auth.token.role == "admin"; } match /products/{productId} { allow read: if true; allow write: if isAdmin(); }; (3) User-owned resources: allow write: if request.auth.uid == resource.data.ownerId; (4) Role stored in Firestore: look up user role from Firestore within rules: function getUserRole() { return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role; } allow write: if getUserRole() == "editor". Note: get() in rules costs one read per evaluation; avoid in high-traffic paths. Custom claims are more performant as they're embedded in the auth token. Custom claims are limited to 1000 bytes per user.