The Case for Granular Permissions

Published by Keanan Koppenhaver on August 24, 2021
image

When it comes to implementing access control in your application, the scheme you decide to use can either make authorization easy to manage as your application and user base grows, or it can really paint you into a corner. There are two commonly used authorization patterns, and choosing the correct one for the application you’re building is crucially important.

An Introduction to Permissions

Different users will need different levels of access to your application, depending on their responsibilities. The two basic ways to grant permissions to your users are through role-based access control or attribute-based access control. Here is how each method works in practice.

Role-Based Access Control (RBAC)

With role-based access control, you create roles encompassing a specific set of privileges that will be granted to any user who has been assigned to that role. For example, if you run a blog, you might have roles for an administrator, who can do everything on the site—including adding new users or deleting the entire site; an editor, who has privileges to interact with the content; and an author, who can only submit and edit their own posts.

yellow-table

If you grant the editor role to a user, they get all the privileges associated with that role. There is no real way to give the user more specific permissions (such as being able to edit only posts tagged with politics) except by creating a new role. This works reasonably well for small to medium-sized sites with a small group of users. As the site grows and the number of users increases, compartmentalizing access becomes difficult and cumbersome. You might even end up having many highly specific roles with just one or two users assigned to each of them—defeating the benefit of having roles in the first place.

Attribute-Based Access Control (ABAC)

On the other hand, attribute-based access control grants users permissions based on certain attributes about them and the data they are trying to access. Attributes could be their title, their department, what piece of data they are trying to access, what department that data belongs to, or any other data held about the objects in the system.

yellow-table-2

Because you can check a user’s attributes against the written set of policies, giving a user one additional permission is much easier than having to assign them to a completely new role, as you would need to do with RBAC. This means your authorization system can be a bit more flexible as it grows, even though it may be more difficult to initially configure when your application is just getting started.

Simple Permissions vs. Secure Permissions

Authorization and permission systems, like most any system in a codebase, usually start simple but become more complex as the application grows. This means that what is best suited for your application initially might not be the best option as you continue to grow. As your systems become more complex, you will also start to run into edge cases with your authorization system, which can make maintaining a homegrown permissioning system more and more of a strain on your developers. This is why more providers over the past few years have begun to offer authorization as a service, allowing you to outsource some of these concerns so that you can focus on your core business logic. The limitations of the DIY approach are most obvious when a team decides to start with the RBAC model and go from there.

Limitations of RBAC

As previously discussed, RBAC is the most intuitive and basic authorization model to get started with. When your application is simple and users can be defined into just a couple of roles, authorization can be handled easily. In addition, this model of authorization is clear to end users and relatively easy to audit. However, when you want to give users more customized permissions that fall outside the well-defined roles, this system starts to break down a bit. You’re stuck with either “promoting” a user to the next role, which may give them more permissions than you really want them to have, or creating a new role specific to that user. Creating a new role might be the right option here, but it can often result in roles that are hyper-specific and only have one or two users assigned to them, which removes many of the benefits of the RBAC model.

Implementing the ABAC Model of Authorization

The ABAC model, while slightly more complicated than RBAC, can be implemented in three relatively straightforward pieces:

  • Policy Enforcement Point: This is the “first line of defense” and is responsible for encompassing all the data that you want to apply ABAC to. The Policy Enforcement Point inspects each request and generates another request, which it will send on to the Policy Decision Point to determine whether the request should be authorized.
  • Policy Decision Point: The Policy Decision Point is where all the authorization logic lives. It takes incoming authorization requests from the Policy Enforcement Point and decides whether to permit those requests to proceed or deny access. If it does not have enough information in the policies it has been configured with to make a decision, it can ask the Policy Information Point for more information.
  • Policy Information Point: The Policy Information Point is used when the Policy Decision Point needs more information, such as from an outside database or authorization provider. It provides information to the Policy Decision Point to aid in making a permit/deny decision on any particular request.

Even though this is a bit more to set up than an RBAC, putting this fine-grained authorization system in place when your application is relatively new will ensure that it can scale with you. ABAC has the ability to add granular policies as needed for particular users or groups of users. This avoids the issue of having to create ultra-specific roles that plagues some larger-scale RBAC implementations.

As more applications move to a microservices architecture, implementing the ABAC model with an external permissions management system makes more and more sense. It allows you to centralize your policy definitions and all the other permission-checking logic that your app might need. A tool like Cerbos can greatly decrease an application’s time to market by allowing the development team to ship more quickly and ensure that all the authorization edge cases are handled. By outsourcing the authorization portion of your application, your development team can focus on your core business logic while still being able to define granular permissions. This will allow you to scale without authorization becoming a bottleneck.

How Do You Get Started?

When you’re just beginning, it’s important to keep things simple. An authorization system with granular permissions allows you to implement only what you need without restricting you as you grow. This additionally forces your API to check for permissions at a more specific level, which means your application will be more secure by default. And when you implement the ABAC model with a third-party tool like Cerbos, you get more granular controls than you would with the RBAC model while enabling your application to scale to your various business needs, all without having to maintain your own authorization system. This allows you to focus on your core business logic and make your application better for your customers as you continue to keep it secure.

About the author:

Keanan is the CTO at Alpha Particle where he helps publishers modernize their technology platforms and build their developer teams.

Book a free Policy Workshop to discuss your requirements and get your first policy written by the Cerbos team