As a developer, there's always a set of features you end up coding again and again in every single application. The authorization logic that defines what action a given user can perform is one of them. It's no surprise then that decoupling authorization and security functions is becoming the norm for many organizations that want improved productivity, security, and reliability.
Decoupled authorization solutions provide out-of-the-box best security practices that allow developers to outsource specific security functions to external services or libraries so they can focus on implementing business logic. It means that they don't have to spend time and resources on maintaining their own authorization logic.
In this article, you'll learn about decoupled authorization and why it's becoming so popular.
To understand decoupled authorization, let's consider how authorization is traditionally handled and why it's not an ideal approach.
Authorization, in short, is the process of determining whether a user or service is allowed to perform a specific action. Actions can be classic access and data manipulation such as creating, reading, updating, or deleting, or they can be business-oriented, such as approving, acknowledging, or accepting.
Traditionally, authorization happens in multiple layers of an application stack, from filtering IPs of malicious sources at the DNS level to controlling read/write access to a database. Authorization logic is also often seen at the load balancer level to prevent common cyberattacks.
DNS and load balancer levels are often tackled by sysadmin and security experts in operations. Developers focus on the applications layer and the resource layer since they need to configure their applications to access those resources. Developers would also be concerned with the authentication proxy as they need a trusted source of information to implement the authorization logic.
Let's delve deeper into these three levels developers work with.
At the proxy level, a user's identity is authenticated and verified. The proxy layer provides information about the user's identity and any authentication details. This layer is usually handled by an authentication server or service, such as OAuth or OIDC, but it often supports various policies to reject the unauthorized request as early as possible.
At the application layer, the user's identity is matched against the application's authorization logic to determine what the user is authorized to do. This layer ensures the user has the appropriate privileges to either access resources that contain sensitive data or perform an action related to an application process.
At the resource layer, the application credential is matched against the resource's access control list to determine whether the user is authorized to read or write data to a specific location. This layer ensures the application has the appropriate privileges to access the resource or perform the action.
This segmentation of the authorization layer can be hell to maintain for developers. Each tool or product has its own paradigm, which means you must learn several approaches to configure or code authorization logic. Imagine doing this at some scale.
The natural solution to this pain point is to opt for a unified, or decoupled, authorization solution, as illustrated in the diagram below. It involves extracting the authorization logic from each component and creating a unique framework that consumes policies from a repository. The framework then returns an evaluation of the authorization decision based on the defined policies.
In other words, decoupled authorization is the process of outsourcing the authorization logic from the application layer(s) to an external service or library. It allows the authorization logic to be updated independently of the application, which leaves developers free to focus on the business logic of their application.
In a decoupled authorization scenario, the application will always start by querying the authorization server to validate the user's permission. If the authorization is successful, the application continues its task and returns a response to the user with the requested information. Otherwise, the request is blocked, and the user receives an error message (usually a 403 HTTP status code).
As you can probably already deduce, decoupled authorization has many advantages for organizations seeking to improve their security, reliability, and productivity and for you as the technical person who is tasked with implementing authorization.
The foremost advantage of decoupled authorization for most organizations is its inherent flexibility and customization capabilities. Changes to authorization rules can be made easily without affecting the rest of the application. This allows authorization rules to be tested independently without affecting the main application, and as a result, the policy frameworks can be battle-tested to ensure the best security. For example, you can restrict access to resources quickly by updating a policy and deploying it to production, all without touching any code. This helps your team be more agile in adapting to changing requirements.
Alongside this, decoupling authorization can, indirectly, contribute to cost reduction. It allows for a more efficient development process, minimizing code duplication by abstracting the authorization logic into simple calls to the authorization server. While the link to cost reduction might need further context to fully appreciate, the speed and iteration benefits can contribute to an overall more efficient operation, with potential financial savings over time.
Decoupling authorization can also prevent mistakes and bad practices due to a lack of expertise. Decoupled solutions use proven techniques such as ACL (access control list), RBAC (role-based access control), or ABAC (attribute-based access control), and their validation logic is coded by security experts. It forces you to adopt such standards while reducing the amount of code and time spent implementing such logic, a huge win-win.
Lastly, having a central authorization server also has the benefit of being able to provide audit logs for all actions performed in the system. This feature, combined with the fact that all policies are stored in a single repository, makes security audits and reviews much easier. You can see what policies are in place at a glance without having to go through hundreds of thousands of lines of code. A central policy repository also makes it easy to track policy changes if you are using a version control system such as Git and to conduct security audits and reviews.
OK, so decoupled authorization seems like a good idea. However, is outsourcing a security function also a good idea? Well, yes, you can see this pattern elsewhere too.
The most common security function that's outsourced is authentication. Authentication validates the identity of a user or service and returns tokens (cryptographic identifiers) that allow the rest of the system to trust the bearer of the token. Implementing an authorization logic can be complex since it requires good security knowledge, especially in protocols such as OAuth 2.0, OpenID Connect (OIDC), and SAML. It's something you want to be doing every day, especially if you can rely on trusted solutions.
Encryption and threat management are two more complex security functions that are often outsourced. Encryption relies on deep knowledge of cryptographic algorithms. Few organizations can afford taking the risk of misencrypting data that would make it unusable. Similarly, threat management, such as bot detection, is a complex process that involves building an AI model that can predict the probability of a given user being a human or not.
Identity management is also commonly outsourced. Building a secure system that can store users' sensitive information, such as emails and passwords, may seem simple, but it's not. Instead of starting from scratch and taking a risk, it's increasingly common to rely on third-party solutions like AWS Cognito, Auth0, or Okta. Solutions offering user management usually include authentication as those two activities go hand in hand.
Managing audit logs and keeping track of users' interaction with the system can also be outsourced using an aggregator, such as Auditbeat for Elasticsearch. An aggregator collects audit data from various systems and creates an aggregated view. It's virtually impossible to process audit logs without an external solution.
So, yes, outsourcing security features is nothing unusual. Major components such as authorization, identity management, and audits are already handled that way. Decoupling authorization from your application code seems like another step in that direction.
Decoupling authorization means relying on a third party, so you need to consider the potential risks that come with it so that you can manage them well.
Firstly, vendor lock-in can feel like loss of control since you can rely only on the features of the solution you've chosen. The language of your policies and its configuration structure will be imposed by the solution you use. If you find that a feature is missing, you may struggle to achieve your goals, and moving to another solution may be complex. It's therefore of paramount importance to choose your solution well.
That means making sure you select a solution that can support your workload and is highly available. Otherwise, the authorization component may become a bottleneck or, worse, the single point of failure. For example, you may want to evaluate the scalability of the solution and its ability to handle your traffic load, including periods of increased traffic or sudden spikes in demand. You will need to evaluate the risks of outage and how to mitigate them.
Lastly, using an authorization server means adding a call to another application, which means added latency to your application. So make sure the solution you select is performant. If you opt for a SaaS solution, consider the provider's geographic proximity to your application. The better alternative is, of course, to have a solution that can be deployed in your own infrastructure.
Having security concerns means your application stack likely has several layers of authorization from the network level down to the resource levels and through the application itself. The issue with this approach to authorization is its complexity and lack of visibility. For instance, at the application level, developers may not realize that they're writing the same code repeatedly to check who can do what.
This is where the idea of decoupling authorization logic from the main application comes into play. It allows developers to outsource repetitive tasks and offers increased visibility on your policies. This approach reduces the overhead of managing authorization logic and allows you to focus on implementing business logic. Decoupling authorization also enables policy frameworks to be tested independently, increases visibility, and provides comprehensive audit trails.
Decoupling authorization is a powerful tool that can help organizations improve their security and reliability. However, you need to carefully evaluate potential risks before selecting your solution provider. This process includes considering some downsides, such as being aware of vendor lock-in and the need to select a solution that is both performant and highly available.
If you are interested in a decoupled authorization solution, consider Cerbos to easily implement and manage fine-grained access control in your applications.
Book a free Policy Workshop to discuss your requirements and get your first policy written by the Cerbos team
Join thousands of developers | Features and updates | 1x per month | No spam, just goodies.