Right now we're implementing a (honestly overly complex) role-based permissions system where users will be assigned to roles and those roles will be granted permissions on some combination of resources. Fairly traditional, and I think fairly straightforward to implement database-wise by linking a table of
users with a table of
roles linked to a table of
permissions, which have a reference to the resource type they're a permission for and a simple bitmask identifying the CRUD permissions they've been granted.
That said, we've got two edge cases involved:
- First, there are administrator users who have unique permissions which can't be granted to users. Some of these are specific features which don't really map nicely with database tables and resources and are specifically available only to administrator users
- Second, since we're a multi-tenant system we have a group of in-house users who can access any database. While the tenant's users all sit within the same database as the tenant's data, these support users all sit in a separate database; otherwise they act as administrator users, occasionally with additional permissions specifically available only to them (again)
Normally the level of specificity required for these users makes me want to move the roles into the application code, but I can't do that because tenants need to be able to manage and assign their own roles, up to and including the creation of new administrators. What this boils down to is that users will likely end up having some combination of roles and attribute-based access control in place: roles for most users, attributes lookup for special cases. So basically hybridizing ARO and attribute-based access control.
My alternative solution here is to create hardcoded roles in the database, potentially reserving the first ~10 or so IDs in my
roles table for "special" roles with hardcoded behaviour. Which also feels nasty.
Which approach should I take? Or better yet, is there an alternative approach I haven't thought of as yet?