Refactor Parse ACL/RBAC to be more scalable and extensible

I think I wrote on here before about a SaaS based ACL approach where multiple companies can have roles associated to a CRM product for instance sales module. The approach suggested was to create roles for each company for each module that a user should be able to access. so if an org ID is 1x2a3b4 then the sales role would look like: 1x2a3b4_sales

this is fine in a flat hierarchy but its very messy as 100s of companies get added. My proposal would be to extend ACL to have a “domain” value, then you can create as many roles like “sales, user manager, admin” rather than “1x2a3b4_sales, 1x2a3b4_user_manager, 1x2a3b4_admin”.

the structure of the acl on the object would be like:

_acl: {
org: [“1x2a3b4”],
role: sales: {r/w},
role: user_manager: {r/w},
role: admin: {r/w},

I leave org as an array of org IDs because its very likely and useful that you can create sub orgs/divisions etc.

The way it would work would be basically if org exists in the acl we simple restrict by that org ID which would be assigned to the user and likewise a user may have an array of org IDs. perhaps this could be a server flag to enableExtendedParseACL: true

Im happy to try to take a stab at this in my spare time, do you guys see any issues with this approach ? do you have an guidance on where these changes would need to be made - I can investigate of course but rather know how big an undertaking this is in my spare time before digging super deep

Maybe it can even be better as a 3rd party plugin for parse, which i also dont know where to start with :slight_smile:

If this feature was standard and very well supported, I would definitely use it !

1 Like

I think it makes more sense than the current ACL, I think in general they area around roles and ACL needs a refresh especially documentation wise, would love to make some helper functions also super useful would be to return a given users roles in the Parse.User.current() so that’s it’s not a separate network call, for me this should be passed clientside by default when you auth

If CloudCode wasn’t a singleton, one could simply create a new site for each tenant and then wouldn’t need to fiddle with ACLs at all. I’ve not looked into this to see how difficult it would be to change, but I feel like that’s the cleanest approach by far.

I’m currently building a multi tenant app. The approach I’ve taken for now is to create a Tenant class and each record has a required pointer field that points to the tenant. Each other class’ “before” triggers runs some code that sets a tenant filter (checking for custom headers) on the query so that a given tenant can only ever interact with their own records.

This means that I only have one set of roles (no nested roles like you’ve mentioned) and rely on my tenant filter to further control things.

It’s not first prize, but this is the approach I’ve taken for now.

1 Like