Mehdi
Mehdi

Reputation: 2398

Data Structure and security on Firebase for Multiple authority layers

I am currently designing an App (SaaS) on Firebase services. This app has users we can categorise as

  1. Super Admins - Can do about everything
  2. Admins - Are usually HR people who can create user (employees) and assign privileges through a back end app. Admins are themselves employees.
  3. Employees - Use the front end and have limited privileges like reads on some collections These roles are defined as claims through FireAuth.

This app is used by different companies. Each one has its admins and employees.

The challenge I am facing is how to structure my data in a way that an Admin is only admin of its company and an employee only has access to their data within their company.

Speaking of course in termes of Firestore rules. I tried the approach

match companies/{companyId} {
   allow read, write: request.auth.uid != null && request.auth.token.admin == true;
}

But then this means that any admin from another company can potentially read write on another company.

Another approach would be

match companies/{companyId} {
   allow read: request.auth.uid != null;
   allow write: request.auth.token.admin == true && request.auth.uid = 'someIdOfAnAdminFromCompanyId'
}

But this means that rules have to be updated anytime a user is made admin.

The safest approach would be to create a custom claim for each item in the companies collection and assign that role to the admins of each company. But then you can only create 1000 bytes of data under customClaims.

Same applies to employees who should only be able to read and write on some sub collections of their company.

Any suggestions out there would be very helpful. Thanks

Upvotes: 0

Views: 89

Answers (1)

l1b3rty
l1b3rty

Reputation: 3660

Why not store the admins for each companies in their own collections:

match companies/{companyId} {
   allow read, write: request.auth.uid != null
     && exists(/databases/$(database)/documents/companies/$(companyId)/admins/$(request.auth.uid));
  
   match admins/{uid} {
     allow get: if request.auth.uid == uid;
     allow read, write: if request.auth.uid != null && request.auth.token.superadmin == true;
   }
}

Upvotes: 1

Related Questions