11.05.2009

Is Role Based Access Control dead?

This question has been coming up a lot in different circles lately and it seems like there isn't a great deal of online buzz or conversation about it, so I would like to bring it to the online collective for discussion and debate.

I have contested lately that RBAC (Role Based Access Control) just flat out doesn't work in today's world. There was once upon a time, when applications were much simpler that this concept fit very well in the application security world, but we no longer live in that world.

The problem with RBAC is that it is a big hammer. It is what I like to refer to as an all-or-nothing solution to a problem that deserves a much finer grained answer. To elaborate on this, let me first explain the concept of RBAC.

1. Applications have users.
2. Users need to be be able to perform actions.
3. Actions are associated with Roles that are allowed to perform said actions.
4. Users belong to one or more Roles.

This is a very *simple* solution to the problem of access control in an application, and in simple applications, it works quite well. RBAC is widely supported by vendors and comes built in to most web application containers. It also happens to be the access control mechanism used by most OS vendors (Replace Role with Group and Voila!). There are tons of implementations for J2EE applications such as Spring ACEGI, JAAS, etc.

When you want to check if a user can perform some action you simply use a quick check

   if ( user.isInRole( Roles.ADMINISTRATOR ) ) {
      doAdminStuff();
   }

So what is the problem with this simple, widely supported, very popular means of access control? It's simple really, RBAC has no awareness of the context request for access.

To illustrate this point, consider the following situation.

You have just completed coding a wonderful project management application for Big Humungous Inc. that filled all the requirements, is unhackable, and even has a list of features far exceeding the clients requests. One day you recieve a call that your client is creating a special group of representatives that need to have administrative access to customer accounts that belong to Group A between 2pm and 3pm every Monday, Wednesday, and Friday.

Now you have a problem. A role is an all-or-nothing access mechanism. So you can't just add the users to the Administrator Role, so your only option is to go back into the code and add a new check in the code that says am I in this role, and do I meet all these other requisites to do the requested action. Then you need to implement that code in every place where you would normally ask is the user an administrator?

Now let me introduce to a different approach to Access Control. It goes by many names. Some call it Activity Based Access Control, I call it Context Based Access Control. The concept is simple.

Make your Access Control mechanism aware of context!

There are any number of ways to do this, but I will address that in a subsequent article as this is more about the interface it provides. Adding context can allow you to specify any number of dynamic situation that are taken into account when determining whether a user has access to perform an action. Consider the following:

public interface AccessContext {
   boolean isAllowed( User u );
}

public interface AccessRole {
   // Some methods
}

public interface User {
   // ... Other user'ish stuff
}

public interface AccessController {
   boolean canUserPerformAction( User u, Context c, Action a );
}

public interface Action {
   void performAction();
}

This is a simple outline of how a Context Based Access Control API might look. Now in your code you might have something that looks like this:

   User user = RequestHelper.getUser();
   Context requestContext = RequestHelper.getContext();
   if ( accessController.canUserPerformAction( user, requestContext, new Action( "Delete User" ) );

Of course this is a very simple and open ended example, but it gets the point across rather well and illustrates the ability to solve problems in a manner that allows the AC layer to be as fine-grained or big hammer as it needs to be in any given situation.

To summarize:

1. Role Based Security doesn't address the problems of today's applications.
2. Context or Activity Based Security has the power to address those problems, but there is no force driving it forward.

I have proposed to the ESAPI team that we are in the perfect position to address this problem at the API level. Designing a clean interface that addresses the simple as well as complex control situations is really the difficult part in this concept.

An interesting read if you have a second - it looks like Microsoft had the same idea 2 years ago, too bad they patented it and did absolutely nothing with it.

http://www.freepatentsonline.com/y2007/0143823.html


I would love to hear what the 'verse has to say about this so let's get some conversation going around this topic and see what we can come up with!

27 comments:

  1. As a followup - just found this on the interwebz. XACML from Oracle aims to be a Markup Language to define access control policies and uses some of the same concepts that I have highlighted in my post. The idea of context representing a more complex business specific decision making object that builds on the existing security mechanism.

    Pretty cool stuff...

    http://www.oasis-open.org/committees/document.php?document_id=33416

    ReplyDelete
  2. Interesting post. I just finished a project which does something similar. We used code access security with our own custom CodeAccessSecurityAttribute and IPermission implementations as a hook and then verify permissions based on the user, the access requested (ex. Read/Write) and a key - much like your action.

    If the user attempts something they have no permission for an exception is thrown. Then the onus is on the developer to wrap calls with a "soft" request:

    if(CanUser(user, AccessLevel.Write, "ACTION_KEY")) {
    // do it
    }

    We even created a utility library which uses expression trees to wrap the request and the action into a single call:

    TryThis(() => SomeMethod(), user, AccessLevel.Write, "SOME_KEY");

    We use it for actions as well as securing data at the field level, in which case we omit the key and use the fully-qualified name of the property as the key. We obtain the property's FQN by reading the expression tree.

    Administrators can then grant/revoke user access to specific actions on an as needed basis. The only thing missing from what you've suggested is the ability to provide an expiration window for elevated access to a specific feature.

    The whole thing is working really well. We can be as flexible as needed w/o affecting the actual business logic of the application. If we needed to add the features you mention then we just update the security layer and leave the application alone. The only time it affects the application logic is if we need to secure something that wasn't secured before.

    ReplyDelete
  3. @Mark - That sounds like a good start. The unfortunate thing is that you had to *brew your own* solution to this problem. Authorization can be a tricky thing to get right sometimes, and having to spend time figuring out every way that someone could exploit a bug in your authorization scheme can be a serious issue on applications with strict timelines that need to be adhered to. If you are spending all of your time tweaking and perfecting your own home-brewed authorization and access controls, well than you are not spending that time on getting the features and bugs addressed in the application itself. I would love to see the ESAPI team in a position where we could design the API and push it out to the experts to implement in their respective frameworks. This way, developers can spend their time focusing on the application they are working on instead of trying to build a framework that may or may not solve all of their problems, and may or may not be secure in itself.

    ReplyDelete
  4. It's about time!

    I've been saying pretty much the same thing - down to the same term Context Based Access Control - for a few years, and I always get responses ranging from:
    - blank stares
    - incredulous, non-understanding looks
    - "weeelll.... our IDM/AD/frameworks already give us access control, we dont have to worry about it"
    - "Naaah, we'll just code up a simple add-on application that will give us everything we need - or, maybe just what is simple enough to do quickly"
    - "So, Role based access control, huh?"

    RBAC is a compromise. Albeit, a sometimes necessary one, and a sometimes acceptable one - but not always both together.
    Acceptable - for simple applications.
    Necessary - there are simply no frameworks or supporting infrastructure that provide this now, in a scalable way. This WILL change, and soon (I'm also working on this right now ;-) ).

    Btw, scalable is also a big part of the picture, so while ESAPI might be a good idea (as far as standardizing the interfaces), it wont help the big picture, since creating it in a generic-enough manner is no simple task.

    ReplyDelete
  5. Another side note, XACML is not really an Oracle creation... but you're right, it is in the right general direction, taking context into account... I dont think the specifics are the best they can be, but anyway...

    The difference between XACML and anything ESAPI would include, is XACML as a markup language cannot be used directly. Perhaps ESAPI could be the front-end API that produces and consumes XACML? (With XACML being one specific implementation for ESAPI, obviously generic frameworks are the way to go...)

    ReplyDelete
  6. That is precisely where ESAPI has the power to make these kinds of changes real is in the interface. Ultimately it is up to the users themselves and the people writing the auth(entication)/(orization) libraries to provide their implementations with support for CBAC - Spring, Struts and JAAS (which are probably the big 3) could write a provider class for the ESAPI using their libraries and voila! We would have solid implementations that are already being used by a good share of the Java Webapps on the 'net today. Unfortunately - I think this is a bit of a pipe dream until we can really start getting a lot of marketing momentum behind the ESAPI and getting it's adoption rate up, but that is not to say that it isn't something that could be done. I know that there are a lot of people getting very interested in ESAPI 2.0 so with it's pending release (very very soon) I think we could absolutely start pushing the envelope soon enough to start making more impactful changes in the world of appsec.

    ReplyDelete
  7. Chris, while I definitely commend the idea, I think you're underestimating the complexity of what such a generic interface would entail, assuming it's done right.

    Moreover, even if hypothetically you manage to get the frameworks guys to supply implementation providers (and here you're just looking at the Java fws, of course... bigger picture is needed :) ), that is STILL only half the way there, if that.

    The reason I say this? Simply performing the authZ checks amounts to little - even if hypothetically this is done as granular as possible - without a solid management system behind it. ESAPI obviously is not going to provide that part of it, and neither are the Java frameworks.

    Therefore, you really need to be looking towards IdM/IAM/EAM vendors, to provide the pluggability you would need to put the Enterprise back into *E*SAPI.
    As one of them myself, and with a personal interest in all OWASP works as a member, I would be glad to be the first - however, as a small startup (still in stealth) I'm afraid I dont carry much weight :(.
    Still, if you're interested maybe I can provide some benefit, when it comes around to that...

    ReplyDelete
  8. Avi -

    That is a very good point. There is an addage that goes something like "Your security is only as good as the implementation" (or maybe I just made that up) and I think your point here is very valid. Really, the ESAPI team can only provide the framework for a good security system and some examples of how that security should work in your implementation. But first and foremost, the ES*API* is just that, an API, and as such, we really don't have much foresight into how the real-world controls will be implemented. There needs to be strong vendor participation in the development of the API and that is an area that I feel we have been lacking. Right now, we ship the ESAPI with a very basic FileBasedAuthenticator which would *hopefully* never be used in a real world app, unless the needs of that app are particularly simple. Most web applications already have some sort of identity and access management platform in place (whether it be homebrewed or otherwise) and regardless of the strength of that platform, they are responsible to maintaining the management interface for identity and access control in their application. If we were able to get buy in from some of the bigger frameworks out there like JAAS and Spring, and also be able to tie this into management solutions for identity and access control, it would make it very easy for people to implement and could provide a reference implementation of what an authenticator should look like that is usable in real-world applications.

    ReplyDelete
  9. Well, I implemented such a mechanism back in 1999 for a corporate intranet.
    The solution worked fine for *static* contexts. However, contexts are often dynamic, and that is more difficult to implement (e.g. a department manager can manage content of his own department, but only view content from another one). We finally managed to implement this, but it required a lot of custom implementation on top of acegi.`
    The example user.isUserInRole() is already bad, and not really RBAC. Ideally, it should be user.hasPermission(). By using user.isUserInRole(), you are hard-coding the permissions that a certain role has right into the code. And that is really a bad thing. We also had to code around that. We ended up with a nice user management, where roles could be managed through the web interface (including assigning permissions to roles in specific context). To check for permissions, we only had to call user.hasPermission(context, permission).

    ReplyDelete
  10. The implementation specifics were not the main point of what I was trying to get acrossed with this post. The main point was that RBAC is well beyond it's years of usefulness and a decent replacement is yet to be released to the general population. I think Context Based Access Control is the answer to this problem. I think you illustrate this as your opinion as well in your comment. You are absolutely right that a CBAC system needs to be accepting of both static and dynamic contexts as well, and yes, this is a very tricky thing to do. I believe that in a way I addressed this in my followup post More on Context Based Access Control.

    ReplyDelete
  11. Zed Shaw has a great speak on this.
    Built a DSL for an app as a result of this understanding.
    http://blog.cusec.net/2009/01/05/zed-shaw-the-acl-is-dead-cusec-2008/

    All the best Chris!
    MarkT

    ReplyDelete
  12. Access control is a system which enables an authority to control access to areas and resources in a given physical facility or computer-based information system. An access control system, within the field of physical security, is generally seen as the second layer in the security of a physical structure.

    ReplyDelete
  13. I believe that one other layer needs to be added to this. WHEN in the web/application stack to check. From a recent Spring 3.0 tutorial, it seems that object access (dbase, et al), and 'point of system departure', i.e. an API or web interface are required. Generically, this is: At the 'Safe/Repository', and at the structure exits/windows/doors. ANYTHING Can happen in between the safe in the floor and the doors, and it will be irrelevant, if the Safe can't be opened and no valid information can be taken outside by unauthenticated persons or authenticated persons under unauthorized circumstances.

    ReplyDelete
  14. Guys.. Am a beginner and looking for nice tutorial about XACML. I went through the whole stuff in many sites but that doesn't give any detailed syntax procedures like W3C gives for XML. Sp pls if u guys know any material or links that guide the new beginners like me , it would be much helpful.. Mail id : sridhar_48@live.com

    ReplyDelete
  15. I came across this post via a search for ACL and RBAC. I'm going to create a C++ library for this. I've read all the interesting ideas here and in the links and elsewhere on the web. I'm interested in why a context is any different than a resource that would be AdminAfter2PM? You'd have to implement the "after 2PM" bits with a context in regard to time, so I don't know if it would be any different with a context. It seems like a context is just another resource to check against. Chris, can you clarify or expand on this please. I'm interested in making a library that is usable in a wide range of applications. If contexts help that, I'd like to understand that better and any other possible ways to tackle this problem.

    ReplyDelete
  16. This comment has been removed by the author.

    ReplyDelete
  17. Everyone seems to be missing the point that RBAC is NOT supported in Java, and calling isInRole() is not the way that RBAC is supposed to work. Your suggestions about adding context is actually the way that RBAC is supposed to work, to a certain extent at least. In other words, if you read any description of RBAC, particularly from this website: http://csrc.nist.gov/groups/SNS/rbac/, you will see that RBAC is NOT the same thing as simple role checking using something like isInRole(). In RBAC, you put "transactions" in your code, which is what their word for "actions" or "operations." So, you would never put a hard-coded reference to Administrator in your code, since what an administrator is allowed to do needs to be dynamically defined and maintained. In your code you put operation specifiers, where you typically combine a noun with verb, such as "CREATE-ACCOUNT", or "DELETE-USER". You then assign these dynamically (probably through a UI) to one or more roles, and those roles can be in a hierarchy or inheritance. Then, you assign one or more roles to users. This way, there is a level of indirection between the user and the operation specified in the code, and this scheme becomes very flexible. That is what is known as Role-based Access Control, and that is NOT what Java has implemented. I see all kinds of people claiming that Java has RBAC, and I just don't see it.

    ReplyDelete
  18. To address Simon's question, in true RBAC, you could specify some hard-coded admin operations like CREATE-ACCOUNT, ACCESS-SYS-INFO, SET-CRON-JOB, and so on. Then instead of making a roles operations a simple true/false, you would make them conditional on other factors such as TIME-RANGE. So, you could give the "night-admin" role the SET-CRON-JOB permission, and also limit it from 2 a.m. to 6 a.m., for example. In your code you would put a check like "session.allowOperation(SET-CRON-JOB)" before the code that actually sets a CRON job, and don't allow it unless the the current session has that operation enabled. When the user logs in, the system would get all their effective roles, and from those, it would prepare a set of allowed operations. Before 2 a.m. or after 6 a.m., the SET-CRON-JOB would be OFF, but within that time period, it would come back as TRUE.

    ReplyDelete
  19. In this way, you don't have ANY roles hard-coded in your code, and what you do have hard-coded aligns very well with the actual code that is there, so it would only have to change if the program functionality changes. This also allows the user to highly customize what it means to be an administrator, or manager, or developer, etc., and to invent or remove roles at will. This is truly the way all authorization systems should work, in my opinion.

    One more thing: to restrict a person's roles to particular business objects, such a person being a "project manager" only for certain projects, I find this is best done by allowing a user's roles to be assigned not just to the User, but to the User and a particular business object. So, in this way, it becomes an ACL for that business object, but the ACL is made up of ROLE mappings, linking a User to a Role within a specific business object.

    ReplyDelete
  20. Very interesting, currently I am thinking how to go about implementing RBAC in my web app, the best possible way.
    The filling I have is RBAC is good till the point I define it for one ecosystem (as context here)
    for eg. we need
    1. Admins and users for set of groups for ecosystem A
    2. Admins and users for set of groups for ecosystem B
    3. SuperAdmin for 1 & 2
    4. Admins for the ecosystem should not have any access in other's ecosystem
    Ken thanks for detailed comments, let me know if you have any better idea.
    - Prashant Upasani

    ReplyDelete
  21. perfect explanation about java programming .its very useful.thanks for your valuable information.chennai's no.1 java training in chennai | top 10 java training institutes in chennai

    ReplyDelete
  22. Nice and good one, very impressive and informative one. thanks for sharing your valuable information.. it is very useful for me to learn and understand.
    Java Training in chennai

    ReplyDelete