Home > Enterprise >  Can I overlap Firestore security rules to prevent the use of the OR operator everywhere?
Can I overlap Firestore security rules to prevent the use of the OR operator everywhere?

Time:06-12

I have a bunch of collections to define security rules for and they all have logical OR operators in them to account for admin rights. Here is one such example:

rules_version = '2';
service cloud.firestore {
    match /databases/{database}/documents {
        function isAdmin() {
            return request.auth != null && get(/databases/$(database)/documents/userProfiles/$(request.auth.uid)).data.admin == true;
        }

        function isSignedIn() {
            return request.auth != null;
        }

        function isOwnDocument() {
            return request.auth.uid == request.resource.id
        }

        match /userSettings/{doc} {
            allow read: if isOwnDocument() || isAdmin();
            allow write: if isOwnDocument() || isAdmin();
        }
    }
}

Could I, instead, declare admin rights up front and omit the OR operator?

rules_version = '2';
service cloud.firestore {
    match /databases/{database}/documents {
        function isAdmin() {
            return request.auth != null && get(/databases/$(database)/documents/userProfiles/$(request.auth.uid)).data.admin == true;
        }

        function isSignedIn() {
            return request.auth != null;
        }

        function isOwnDocument() {
            return request.auth.uid == request.resource.id
        }

        match /{document=**} {
            allow read: if isAdmin();
            allow write: if isAdmin();
        }

        match /userSettings/{doc} {
            allow read: if isOwnDocument();
            allow write: if isOwnDocument();
        }
    }
}

Would this be a good practice?

CodePudding user response:

Could I, instead, declare admin rights up front and omit the OR operator?

Yes!

I just checked the Rules Playground in the Firebase Console.

enter image description here

To try the Rules Playground, go to the Rules tab of Cloud Firestore and click on Rules Playground. You will see it bottom left to the Rules Editor. There, you can build the data and an authenticated state and from there simulate a request.

Would this be a good practice?

Yes, certainly. It will make your Firestore Rules cleaner. So you won't need to be putting || (or) in every match.

Explanation

From the Firebase Docs:

It's possible for a document to match more than one match statement. In the case where multiple allow expressions match a request, the access is allowed if any of the conditions is true

So when isAdmin() is true (and because it is declared upfront for all documents), Firestore will allow access for the documents.

From the question comments ...

can you elaborate on what you mean by setting admin through custom claims?

Custom Claims is a feature in Firebase where you can assign different roles to users. You can use custom claims to set admin privileges, teacher permissions, or any role your app needs.

Custom Claims take valid JSON (preferably key-value pairs with boolean values).

Custom Claims on a user can be accessed in different parts of Firebase:

  1. In the clients, through idToken,
  2. In the admin SDK, through auth.token, and
  3. In the security rules (for Firestore, Realtime Database, and Storage).

So, in either of these parts of Firebase, you can check the custom claims on an authenticated user to give them access to resources or not.

Note that custom claims are not meant to be used as a store of data to extend the User object from Firebase Authentication. They are primarily there for security rules. Firebase will reject custom claims that are more than 1000 bytes.

Also, you can only manage custom claims on your projects in the admin SDK.

Learn about custom claims here.

  • Related