Lately I've been considering the best access control model to use in my application. I've been reading on RBAC and the role concept is nice (especially if you have a huge amount of different permissions), however, I'm not sure how applicable it is to hierarchical user management like the following:
Every user belongs to one or more groups. Groups are organized into a tree (like a directory structure). Both groups and users can be assigned permissions (or roles, if we're talking RBAC) and there should probably be some kind of inheritance (i.e. users and groups inherit permissions of the groups they belong to) and overriding functionality. The purpose of groups themselves is not only permission management - they will have other uses in the app.
I imagine all of the above wouldn't be too problematic to design further and implement if permissions were used without roles ("roles" are collections of permissions in RBAC terminology) since permissions are very granular while roles are more monolithic. Implementing permission inheritance/overriding at the group/user level would not be too difficult. Doing the same with roles would probably be more tricky, but on the other hand, roles are more easily understandable to an average user.
Right now, I myself am leaning more towards the "permissions only" model because:
However, if I was presented with a logical and easily understandable role-based model that had an advantage over the "permissions-only" one, I would seriously take a look at it. Are there any well-defined RBAC models (papers, implementations, etc.) already available that could be applied/adapted to the requirements above (I've been searching for them for some time, but those I found were either too restrictive or didn't take hierarchical user management into accoun)? What is your overall opinion on the matter? Is RBAC worth it in this case?
I think a basic RBAC system is as simple as just using a permission system.
Note that the term 'role' in RBAC is something that might limit implementation. What I mean by that is that a traditional RBAC system has rules typical like this:
allow (a) role (to do an) action (on an) object
In pseudocode you might have a method like this:
myRbac.allow(Member, View, Post)
There is, however, nothing that prevents you from abstraction roles. A role typically is a string name. With that string name you can also name your groups and users. 'Role' based then allows for much more than roles if you use it creatively. Call it Object based or something else but essentially it's the same: you allow something to do an action on something.
allow (an) object (to do an) action (on an) object
If you look at it from this viewpoint your implementation will, IMHO, be simple enough to justify the cost of implementation. Don't let the 'role' term limit the simplicity the implementation can have. And if you can do implement it that simple, why not go for it?
It seems like you know PHP. If you take a look at Zend Framework ACL you will see an implementation that is role based. Maybe that will inspire you.
edit: about the hierarchy: It's not difficult to implement hierarchy for roles (object or names by extension). Check if there are any rules for the requested object-action-object. If there are none go up in the hierarchy until you have an allowed or denied. If a user can have more than one role (eg the role of member and is in group Administrators (aka the role called AdministratorGroup)) you must choose whether a deny overrules an allow or vice versa. I prefer to have the allow win when the levels are parallel (eg an action is allowed for role A but denied for role B, our user has both role A and B and role A and B are not related, not in a hierarchy).
Re: your example hierarchy. In Zend Framework ACL this could be like this:
$acl->addRole(new Zend_Acl_Role('Role1'))
->addRole(new Zend_Acl_Role('Group1', array('Role1'))
->addRole(new Zend_Acl_Role('Group2', array('Group1));
$acl->allow('Role1', 'someAction', 'someObject'); // permission 1
$acl->allow('Role1', 'otherAction', 'otherObject'); // permission 2
$acl->deny('Group2', 'someAction', 'someObject');
To be honest it's been some time I've actually done this in Zend_Acl since I'm creating my own system.
The challenge with using groups for custom application permissions is the lack of any relationship between the groups and the resources they are being used to protect. e.g. If I use an AD group to grant access in my custom application, I really don't know what else that group may be granting access to - if I add a user to the group thinking that I'm granting read and approve to my app I could be inadvertantly adding them to a group that grants access to shared folders, others apps, almost anything. If writing your own app I would suggest something like a role-based system (even better roles as part of a claims model with all security maintained external to your app code) where there is a constrained relation between the role and which resources it could be used to grant access to - that way you can see from all dimensions who has access to what and why. Groups represent a black hole from a visibility perspective.
We implement a pretty complex RBAC in our product with polyarchical business roles and technical roles that are constrained per type of resource they protect - http://blog.identitymanagement.com/downloads/ Microsoft's has a new new claim-based programming framework called the Windows Identity Foundation - handles most of the plumbing for you
Patrick Parker
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With