Understanding Role Based Access Control: Advanced Concepts
For some of you steeped in IAM concepts, our previous post on Role Lifecycles seems a bit basic. But many enterprises are still grappling with how to plan for, implement, and manage roles throughout the enterprise. There are many systems which contribute to roles and privileges, so what may seem basic in theory is often quite complex in practice. Today’s post will dig a bit deeper into more advanced RBAC concepts. Let’s roll up our sleeves to look at role engineering!
To get value from roles in real-world use cases requires spending some time analyzing what you want from the system, and deciding how to manage user roles. A common first step is to determine whether you want a flat or hierarchical role structure. A ‘flat’ structure is conceptually simple, and the easiest to manage for smallish environments. For example you might start by setting up DBA and SysAdmin roles as peers, and then link them to the privileges they need.
Flat role structures are enough to get the job done in many cases because they provide the core requirement of mapping between roles and privileges. Then Identity Management (IdM) and Provisioning systems can associate users with their roles, and limit users to their authorized subset of system functions.
But large, multifunction applications with thousands of users typically demand more from roles to address the privilege management problem.
Hierarchies add value in some circumstances, particularly when it makes sense for roles to include several logical groups of permissions. Each level of the hierarchy has sub-classes of permissions, and the further up the hierarchy you go the more permissions are bundled together into each logical construct. The hierarchy lets you assemble a role as coarse or granular as you need. Think of it as an access gradient, granting access based on an ascending or descending set of privileges.
This modeling exercise cuts both ways – more complex management and auditing is the cost of tighter control. Lower-level roles may have access to specific items or applications, such as a single database. In other systems the high-level manager functions may use roles to facilitate moving and assigning users in a system or project.
Keep in mind that roles facilitate many great features that applications rely on. For example roles can be used to enforce session-level privileges to impose consistency in a system. A classic example is a police station, where there can only be one “officer of the watch” at any given time. While many users can fulfill this function, only one can hold it at a time. This is an edge case not found in most systems, but it nicely illustrates where RBAC can be needed and applied.
RBAC + A
Sometimes a role is not enough by itself. For example, your directory lists 100 users in the role “Doctor”, but is being a doctor enough to grant access to review a patient’s history or perform an operation? Clearly we need more than just roles to define user capabilities, so the industry is trending toward a combination of roles supplemented by attributes.
Roles can be further refined by adding attributes – what is commonly called RBAC+A (for Attributes). In our simple example above the access management system both checks the Doctor role and queries additional attributes such as a patient list and approved operation types to fully resolve an access request.
Adding attributes solves another dimension of the access control equation: they can be closely linked to a user or resource, and then loaded into the program at runtime. The benefit is access control decisions based on dynamic data rather than static mappings, which are much harder to maintain. Roles with dynamic attributes can provide the best of both worlds, with roles for coarse policy checks, refined with dynamic attributes for fresher and more precise authorization decisions.
More on Integration
We will return to integration… no, don’t go away… come back… integration is important! If you zoom out on any area of IAM you see they are all rife with integration challenges, and roles are no different.
Key questions for integrating roles include the following:
What is the authoritative source of roles?
Roles are a hybrid – privilege information is derived from many sources. But roles are best stored in a locale with visibility to both users and resource privileges. In a monolithic system (“We just keep everything in AD.”) this is not a problem. But for distributed heterogeneous systems this isn’t a single problem – it is often problems #1, #2, and #3! The repository of users can usually be tracked down and managed – by hook or by crook – but the larger challenge is usually discovering and managing the privilege side.
To work through this problem, security designers need to choose a starting point with the right level of resource permission granularity. A URL can be a starting point but itself is usually not enough, because a single URL may offer a broad range of functionality. This gets a bit complex so let’s walk though an example:
Consider setting a role for accessing an arbitrary domain like https://example.com/admin. Checking that the user has the Admin role before displaying any content makes sense. But the functionality across all Admin screens can vary widely. In that case the scope of work must be defined by more granular roles (Mail Admin, DB Admin, and so on) and/or by further role checking within the applications. Even this simple example clearly demonstrates why working with roles is often an iterative process – getting the definition and granularity right requires consideration of both the subject and the object sides. The authoritative source is not just a user repository – it should ideally be a system repository for hooks and references to both users and resources.
Where is the policy enforcement point for roles?
Once the relationship between roles and privileges is defined, there is still the question of where to enforce privileges. The answer from most role checkers is simple: access either granted or denied – but figuring out where to place the checks can be considerably more complicated.
Role checking can be done at the UI level, such as in a gateway or proxy; it can be in code in the middle tier; and/or it can be performed in the data tier. Notice that “and/or” – role checks can, and often should, occur in several places inside an application. Or – typically for management convenience – it may make sense to centralize all role checks in one place.
The next question is: Should role enforcement be embedded in the application container, or should the application call out to the role engine? All else being equal, the performance and simplicity of an embedded role checker makes sense to us, but your mileage may vary. Even embedded in an application, a role checker should be clearly auditable – preferably implemented as a set of easily updated rules, rather than hardcoded in an application, scattered across a million lines of spaghetti code.
Dealing with legacy systems
Legacy systems – the justification for and mechanisms behind your paycheck – present their own challenges. Very often the only option is to “front end” a legacy system with an authorization proxy or gateway that intercepts and validates access requests.
If an access-checking “front door” won’t work the next option is to use provisioning systems to synchronize or replicate roles from an authoritative source, translate them into the legacy system language such as SAP, and then let the legacy system check roles based on your external data feed. This can work well but involves up-front data cleanup, role/access translation, and an automated provisioning feed.
Otherwise most authorization changes are handled through invasive surgery inside the application. Like most invasive surgery, it is extremely painful at best in the short term, and life (career) threatening at worst. When you are wondering whether to rewrite an internal legacy authorization system, the answer is ‘no’ 99 times out of 100.
It is critical to keep in mind the number of access checks in a real-world system. If your system makes heavy use of roles, as it probably should, then your role system will be taxed in a serious way. Plan for scale and test accordingly. We have seen systems that weren’t, and the results were not pretty – in one memorable case, 3-minutes call center interaction turned into 9 minute affairs, thanks to external role checkers running across a large network. In that case the responsible VP was fired. Ensure your RBAC is efficient and scalable, and meets your business’ performance requirements. We understand this is not easy, but if you do your homework up front, roles can pay big dividends down the road.