16

I want to build a Hierarchical Role Base access control. This is my current schema:
enter image description here

Currently I have two options to build this system:

  1. Attach all required permission to a role (not-hierarchical) enter image description here

  2. Attach only special "level" permissions and inherit the ones that have lower level enter image description here

Is there a better approach or is just depends on my project needs?

I am inclined to choose the Hierarchical one just because of simplicity. If I do so, is there any better way on selecting Permission Levels, maybe using binary numbers?

Option 2 would have some Levels for Roles and I would have some level numbers for permissions. Therefore, when I create a Full Administrator the role will inherit all the other permissions since that would be Level 4 while the other permissions would have a number smaller than Level 4 (or 4000).

Is this overkill?

Cristian
  • 2,390
  • 6
  • 27
  • 40
  • 1
    Don't turn this into a hierarchy. It is more trouble than it is worth. Instead, simply make N different 'roles' (each of the role will represent permissions it contains as individual properties) and assign a role (or more) to each of the users. In the case of multiple roles, simply flatten the permissions as fixed stage. – user2864740 Aug 26 '15 at 17:56
  • 1
    I don't see why inheritance should be trouble. Seems to save a lot of coding and entity accesses. – al'ein Aug 26 '15 at 17:57
  • Because it is 1) much more complicated 2) adds very little (if any) worth in this case. But whatever, do what you are going to do. – user2864740 Aug 26 '15 at 17:58
  • At OOP approach, a `user` class extends it's profile childs. Where is the complication? – al'ein Aug 26 '15 at 17:59
  • @AedixRhinedale Standard SQL is not 'OO' and even much more complex frameworks like EF (which is one of the best there is for this monkey business) do a rather shoddy job of the impedance. There is also the difference between an OO tree hierarchy (a fixed set, eg. classes) and a data hierarchy (eg. tree nodes). – user2864740 Aug 26 '15 at 17:59
  • Well, you got me. I didn't see OP saying anything about dealing with this only inside database. I came here because of the PHP tag. – al'ein Aug 26 '15 at 18:00
  • But, I've said my piece. Have a good time writing the system and learning from it. (I support #1 which is *not* a hierarchy.) – user2864740 Aug 26 '15 at 18:02
  • Option 1 is certainly a lot more flexible/reusable. – rjdown Aug 26 '15 at 18:02
  • @user2864740 So baiscally you say this: For a "paid user" I should assign to them two roles "basic user" and "paid user". Then in turn permissions for "basic user" (edit profile, search post) and "paid user" (create post, edit post, update post). And this combination gives the "paid user" all the required permissions, right? – Cristian Aug 26 '15 at 18:03
  • 1
    Not at all. You could; but there is no need. I'm saying that even with #1 (which is the non-hierarchical basis) there is no reason that a user might only have one role - and if this account for it keeps the system quite flexible and still simple. However the permission aggregation handles along roles, not hierarchies. – user2864740 Aug 26 '15 at 18:04
  • @user2864740 I'm really missing your point. Why don't you build an answer for that? Seems interesting. – al'ein Aug 26 '15 at 18:06
  • @user2864740 I still don't understand your approach. Can you please give an example? – Cristian Aug 26 '15 at 18:27

1 Answers1

15

I recommend going with a variation of "Approach #1" - non-hierarchical Roles.

I've worked with similar systems with great success. While at first this approach may appear 'less structured' it is relatively simple and is very flexible; when allowing multiple Roles-per-User and defining rules for aggregating permissions.

Against Hierarchies (for Roles)

Like an 'OO hierarchy', using a role hierarchy leads to a strict substitution-relationship. This makes it harder to define roles based on changing requirements.

For example, maybe there is a future need for an 'Administrator' account which cannot create their own posts. The hierarchy (and the substitution-relationship it has) prevents this without changing the tree structure itself because a "Full Administrator" is-a "Paid User".

Queries against a true hierarchy are more complex in SQL; especially in implementations that do not support recursive queries, like MySQL. Switching to a hierarchy using a nested-set or materialized approach forces an additional structure over just a parent-child relation.

You Just Don't Need It; the more complex software is the harder it is to write and maintain. While hierarchies are very good in certain cases - such as with a Bill of Material or Genealogy or Directory Structure - there is simply not a 'need' in most Role/Group-Permission models.

For (multi) Roles

Roles, without a 'parent type' dependence, function more like 'OO interfaces' - well, maybe Trait composition would be more apt if analogies are to be stretched. The implementation (read: granted Permissions) of each Role can change independent of any other Role making it extremely flexible. And like interfaces, more than one Role can be assigned to a given User/entity.

Queries against a flat User <M-M> Role <M-M> Permission model are much simpler in SQL (with or without recursive support, or additional structure) because there is simply no Role hierarchy to traverse.

Windows ACL Groups (let's ignore nesting groups) work much like Roles; a User belongs to one or more Groups which grants (or denies, but that's a different situation) Permissions.

Have your Cake and Eat it Too

The variation I recommend, and have hinted to above, is to allow aggregation of permissions across Roles. A simple aggregation model is this:

  • A User has the union of Permissions from all the Roles they are assigned.

    (The effective permissions would generally be built during authorization, but without a hierarchy it is also relatively simple to query in SQL.)

Thus the Permissions are bound per Role with little or no overlap, as show in "Approach #2", with this difference: There Is No Hierarchy.

For example, to allow a special administrator who can search for posts (and delete 'bad' posts), one would simply assign the "Basic User" and the "Limited Administrator" Roles1.

Using a non-hierarchical multi-Role capable system allows this cleanly, shrugging off the burden of a hierarchy, while still providing flexible/composable/configurable Role archetypes.


1 This is not a particular good example. In reality the Roles should have different names (eg. "Account Support" or "Content Moderator") and cover different Permission sets; these will likely change over time based on trial and error and flavor-of-the-month business rules.

While I've spoken against a hierarchy for such, in more complex systems there may be a need to allow relationships between Roles, primarily for grouping of such. This relationship should generally be independent of the effective Permissions applied, existing for other managerial purposes.

user2864740
  • 60,010
  • 15
  • 145
  • 220
  • 2
    Thank you for your insight. It really makes sense not to go for hierarchical structure. The "little or no overlap" combined with "union" really go well with my current project. In your example of the "special administrator" after the two roles "basic user" and "limited administrator" roles are assigned the special administrator would not have the permissions of a paid user. This makes total sense. And yes, in certain situations hierarchical roles would work but that means that the permissions and roles would not (maybe a little) change over time. This is not my case. Can have lots of changes. – Cristian Aug 27 '15 at 13:28