Enable javascript in your browser for better experience. Need to know to enable it? Go here.
Hero banner

Using attribute-based access control to solve role explosion (part 1)

When we think about system authorization, roles, meaning a set of rules regulating user permission to operate on a resource, first come to mind. They’re the common permission model. Creating a role means the rules are static and won’t be updated unless the role is updated. 


Let’s take a library’s book management system as an example. You can assign roles such as reader or librarian so that everyone can perform the actions they need (view books, information maintenance, etc.). However, in a larger library, you might need to create more specific roles such as “second-floor librarian” or new ones such as “publishing company agent.” As the library expands, the entire system might face the problem of “role explosion.”


The library scenario uses RBAC (Role-Based Access Control), a static mode of Access Control commonplace in authorization systems. To avoid role explosion but keep fine-grained access control, we can use ABAC (Attribute-Based Access Control). ABAC has no roles, meaning no "role explosion." It dynamically determines whether the user is allowed to operate on the resource by defining a series of access specifications and using the current user’s attributes to operate the relevant resource.


Concepts and frameworks


  • Subject: A user or a system who starts an operation.
  • Object: The target resource where the Subject operated, such as user data.

  • Operation: The operation from a Subject to an Object, e.g. additions, changes, etc.

  • Attribute: Refers to a set of data related to the SubjectObjectOperation and environmental context data.

  • Policy: Refers to a set of predefined rules that can dynamically generate access control results based on attributes.


To truly implement ABAC, it’s best to rely on a mature framework such as XACML (eXtensible Access Control Markup Language). The ABAC system it defines has four main components:






Policy Administration Point

Point that manages access authorization policies


Policy Decision Point

Point that evaluates access requests against authorization policies before issuing access decisions


Policy Enforcement Point

Point that intercepts a user's access request to a resource, makes a decision request to the PDP to obtain the access decision and acts on the received decision


Policy Information Point

System entity that acts as a source of attribute values (i.e. a resource, subject, environment)

A diagram showing relationships in XACML architecture

Relationships in XACML architecture


The Practice  


MyABAC is the authorization system we built. ABAC’s architecture allowed us to incrementally deliver individual components and features on demand.

A diagram showing the architecture of MyABAC

MyABAC is a special layer between Subject and Object. Whether an HTTP reverse proxy or an API Gateway Lambda authorizer, it’s in charge of intercepting or forwarding requests. We can use a representational instance of frontend and backend to describe it.

A diagram showing the architecture of MyABAC

Now, let’s add the ABAC components.


Iteration 1: First model (PEP)


The core functionality of PEP is to intercept or forward the frontend request. This version of MyABAC has two functions: 


  1. Evaluating request permissions.
  2. Forwarding or rejecting the request. 


Rejecting the request directly returns a HTTP 401 error. To forward it, we need to proxy the whole request. But what should we do for Permission Validation? The “Attribute” in ABAC is the data source used to validate the permission. The only data we can get now is from the request itself or the current environment’s context. We can use a piece of static logic to get attributes from the request itself and verify it with a simple validation. To adapt to different requests, we can create a component called an “Extractor” that works as the logical abstraction of obtaining request attributes. This gives us our first iteration:

A diagram showing the architecture of MyABAC for Iteration 1 (PEP)

Iteration 2: Adding policies (PEP + PDP)


PEP is only responsible for the enforcement of authentication results. The real logic for authentication is implemented in PDP. Therefore, Decision Maker is one of PDP’s primary components. If we use 'Permit’ and 'Deny' to represent the result of the decision, we can set up a PDP client in PEP to pass the attributes obtained by the Extractor to PDP, and then pass the PDP result to Validation to determine whether to forward the request. After the PDP gets the attribute values passed by PEP, it’s no longer a simple evaluation. It’ll be based on a series of Rules, where each rule has its own matching Condition and result (Effect). Each group is called a Policy. In each policy, the rule result is reduced to one Effect according to a certain algorithm (Rule-combining Algorithm). PDP will then summarize the result and return it to PEP as “permit” or “deny”.

A diagram showing the architecture of MyABAC for Iteration 2 (PEP + PDP)

In a real system, PDP and PEP can be directly called by different components. They can also be deployed as different services using HTTP requests. For flexible architecture in MyABAC, we deploy PEP and PDP as two processes communicating internally over HTTP.


The next part will expand on MyABAC through new iterations.

Disclaimer: The statements and opinions expressed in this article are those of the author(s) and do not necessarily reflect the positions of Thoughtworks.

Keep up to date with our latest insights