Authorization is one of the most challenging and inevitable problems that every application must address. Regardless of the access control mechanism (RBAC, ABAC, ReBAC, etc.) you adopt, certain issues must be tackled either immediately or eventually as the application grows.
This blog is part of our Authorization series, aimed at Architects/Principal Engineers responsible for developing authorization solutions for their systems or who are already working on it and feel that there are areas for improvement. We will focus on specific problems we have encountered or anticipate when handling authorization for medium-sized enterprise systems (with hundreds to thousands of users) addressing complex issues across multiple services running on hundreds of servers. In a follow-up blog, we will explore the solutions to the problems enumerated here.
Given the context, we assume that you have already chosen your business rules for access control and are working towards a scalable technical solution based on those rules.
We have encountered situations where access definitions themselves violate conceptual integrity and carry a lot of contextual meanings, resulting in complex and inconsistent access definitions across systems.
Scenarios like these may lead to contradictory definitions, such as:
Such contradictions might result in faulty access definitions, potentially exposing data to unintended users. Although this is primarily a business definition issue, it is worth highlighting, and technology should make the problem apparent so that it can be resolved.
Even with simple and consistent business definitions, inconsistent implementations are possible due to the size and complexity of the system being built. Some main reasons for this problem include:
Having services built across different time periods with varying business requirements.. To a great extent, this problem can be addressed by abstracting out the authorization implementation as libraries for each language we need to support and using them across services
The aforementioned solution for inconsistent implementation will increase the cost of development, as we have to maintain libraries across different languages and ensure consistency and maintenance for all of them.
There is no straightforward solution to this, which we will explore in future blog posts.
Given that authorization is not a direct functional requirement from a user’s perspective, the time spent on authorization should be minimal.
For example, we have seen listing/searching APIs used in enterprise systems that search for all IDs and ensure that each resource has the expected access. This occurs mainly when custom authorization solutions start simple and grow without scalability as a primary goal. We will explore solutions to this issue in future blog posts.
Given that you have a set of access control policies, if you have taken the route of ad-hoc permission checks all over the application, you might not have validations for the policies done exclusively, just for the sake of testing and validating the policies. Once you have something like that, you will be able to avoid the problem#1(Complex and inconsistent access definitions) that has been mentioned. We’ll explore the solution for this in future blogs.
In addition to the above problems, depending on the nature of your system, you might end up addressing some system-specific authorization issues, such as:
We’ll explore the solution for this as well in future blogs.