[Link to the Apache Fortress RBAC-ABAC-SAMPLE project on Github]

[Link to towards-an-attribute-based-rbac-ldapcon-2019-v1 from LDAPCon]

We’ve all heard the complaint, RBAC doesn’t work. It leads to Role Explosion, defined as an inordinate number of roles in a production environment. Nobody knows who must be assigned to what because there are hundreds if not thousands of them.

What’s a system implementor to do? We could give Attribute-Based Access Control a try, but that has its own problems and we need not go there again.

There’s another way. RBAC allows the usage of dynamic attributes.

Recent standards include dynamic policies, most notably, ANSI INCITS 494 RBAC Policy-Enhanced

The existence of entities to conveniently apply dynamic policies, e.g. User-Role and Role-Permission.

No language discouraging the usage of dynamic attributes alongside RBAC in the standard.

Indeed, dynamic attributes are encouraged if not prescribed. Here’s where I should be pointing to evidence substantiating my arguments.

This brings us to Apache Fortress and a new enhancement to use dynamic attributes.

What is Apache Fortress?

Both followers of this blog (wife and boss) know about Apache Fortress. Especially my wife. It’s the itch that leads me to three years of work in a garage, alongside two of my brothers, who got dragged in also.

It’s also an implementation of the classic RBAC specification – ANSI INCITS 359. If anything’s prone to exploding roles, it’s Apache Fortress.

How are we going to stop the dang exploding?

Described in a JIRA ticket yesterday, and checked into the Apache Fortress Core Repo last night. The idea is best explained with a story.

The Tale of Three Stooges and Three Branches

Once upon a time there were three branches, North, South and East managed by The Three Stooges that worked there, Curly, Moe and Larry.

They were nice blokes, but a tad unruly, and so we try to keep them separated. Curly works in the East, Moe the North and Larry runs amok in the South. All three are Tellers, but each may also substitute as coin Washers at the other two.

All is well because each Branch has only one Teller. It’s never good when two Stooges combine without one being in charge.

Here are the Users and their Role assignments:

Curly: Teller, Washer

Moe: Teller, Washer

Larry: Teller, Washer

By now we know where this storyline’s headed. How do we prevent one going off-script, wandering into another branch, activating Teller, and running slipshod?

The classic Role explosion theory goes like…

Create Roles by Location with User-Role assignments:

Curly: TellerEast, WasherNorth, WasherSouth

Moe: TellerNorth, WasherEast, WasherSouth

Larry: TellerSouth, WasherNorth, WasherEast

This works pretty good with three branches and two roles but what about the real-world? How many branches will the medium-sized bank have, a thousand? How many types of roles, at least ten? If we follow the same Role-by-Location pattern there’d be over 10,000 Roles to manage! We may be keeping our Stooges in check, but at the IT team’s expense. Our roles have indeed exploded. What now?

Time for something different, back to the earlier discussion over using attributes. Let’s try controlling role activation by location, but store the required attributes on the user object itself.

User-Properties to store Role-Locale constraints:

Curly: Teller:East, Washer:North, Washer:South

Moe: Teller:North, Washer:East, Washer:South

Larry: Teller:South, Washer:North, Washer:East

What just happened here? It kind of looks the same but it’s not. We go back to only needing two Roles, but have added dynamic policies, Role-Locale, to properties stored on the User. Our medium-sized bank only needs 10 roles not 10,000.

Now, when the security system logs in a User (createSession), it pushes its physical location attribute into the runtime context, e.g. North, South or East, along with the already present Userid attribute. The security system compares that physical location, along with its corresponding properties stored on the User, to determine access rights, specifically which Roles may be activated into their Session.

Sprinkle in a policy that defines the role to constraint relationships.

Global Config Properties store Role-Constraint mappings:

Teller:Locale

Washer:Locale

That way when the security system activates roles it knows to perform the extra check on a particular role, and which attribute to verify.

In addition to location, we can constrain role activation by project, organization, customer, account balance, hair color, favorite ice cream, and any other form of instance data imaginable. There may be multiple types of constraints applied to any or all roles in the system. It truly is a dynamic policy mechanism placed on top of a traditional Role-Based Access Control System.

With this minor change to the security system, our IT guys return to the good life without worrying about exploding roles or what the Stooges are up to. 🙂

The End