What is authorization?
Authorization is the process of granting or denying access to specific resources based on a user's verified identity. (Not to be confused with Authentication, which is about verifying a user's identity). In simpler terms, it’s about who can do what in your application once they have logged in, and under what conditions.
Application-level Authorization can be managed through different authorization models. These authorization models determine the level of access or permissions granted to users based on factors such as user roles, attributes, contextual information, or a combination of these factors.
These decisions are made and enforced by rules, which are called policies.
There are several models in which these policies can be structured. The most common are Role-based access control (RBAC), Attribute-based access control (ABAC), and Relationship-based access control (ReBAC).
What is authorization as a service?
Authorization as a service means outsourcing the management of permissions and access control in your application to a third-party service. In the past few years, new authorization providers have emerged, providing a varying set of services and approaches to solving your authorization challenges.
In short, the main benefits of adopting an authorization service are both streamlining the development process and ensuring that your application is more resilient and easily deployable. By leveraging an authorization service, developers can concentrate on building the core features of their application, freeing up valuable time and resources that would otherwise be spent on creating and maintaining their own authorization and permission management systems.
Proper implementation of authorization systems (Or the lack of it) is considered by many the biggest concern in application security, with the latest OWASP "Top 10 API Security Risks" report once again listing "Broken Object Level Authorization" as its top 1 vulnerability.
That being said, let’s dive into each of these points and discuss it in more detail:
Why Would You Need An Authorization Service?
Building a secure application is a top priority for any developer, and managing permissions or authorization is a key component in achieving that. The question of how to manage the authorization layer in your application is relevant to almost any application out there with a varying degree of complexity.
A lot of ink has been spilled over the debate of build vs. buy when it comes to security features. In some areas, such as authentication, a solid consensus has been reached in the last few years that developers should not roll their own authentication. his type of shift isn’t limited to the security space - building your own payment infrastructure instead of using solutions like Stripe has been considered absurd for a while now.
With Authorization, the question of build vs. buy has not been debated as much, as full-stack Authz solutions are only now beginning to emerge. You can read a more detailed discussion of this subject in this blog.
That being said, let’s go over the main benefits of adopting an existing authorization solution:
Enhanced Security Expertise: Authorization is a complex problem that requires in-depth knowledge to solve properly. Third-party authorization services are developed and maintained by security experts, solely focused on making sure the solution they provide is up to the latest industry standards. This reduces the risk of security vulnerabilities and data breaches.
Saves You From Reinventing the Wheel: While a complex problem, authorization is a common problem constantly encountered by dozens of developers. Utilizing a ready-made service instead of building one from scratch saves development time, allowing developers to focus on core functionalities and improving time-to-market. Authorization is more than just the enforcement infrastructure - It is also a long set of interfaces (both UI and API) that most applications end up needing sooner or later.
Compliance and Regulations: Established authorization services come with built-in compliance features which allow you to implement the security and granularity levels required to adhere to industry-specific regulations and standards such as HIPPA, SOC2, and ISO 27001.
User Experience: Some authorization as a service solutions provide easily manageable user interfaces to manage your authorization layer, or even generate policy as code. This prevents a situation where developers become bottlenecks in creating and managing policies - including all stakeholders in the conversation.
Can You Build an Authorization Service Yourself?
While it is possible to build an authorization service yourself, it comes with significant challenges. A homebrew solution would have to meet at least these basic requirements:
The service must match the availability of your existing stack, ensuring it can handle the constant requests from other services.
It must process requests with low latency, typically aiming for query response times below 50ms. If each takes more than 50-100ms, the performance of your application is basically ruined before it even starts to handle its own core logic.
You'll need to create a storage system for your authorization data model, including roles, relationships, and policies, with the ability for administrators to modify them.
Not all authorization-related data is available or relevant for every authorization check request. Some data, such as user attributes, object metadata, and entitlements, may need to be fetched from external sources such as IAM providers, application databases, external services, etc. This data needs to be propagated into the authorization layer when required and managed in a real-time fashion.
Supporting various authorization models (Such as RBAC, ABAC, ReBAC, or any model relevant to your application) while maintaining fast and reliable query responses is essential.
Authorization systems require ongoing critical maintenance and development as new requirements continue to funnel in from customers, security & compliance, and the expansion of the application itself.
If you prefer to avoid the engineering effort, using an authorization service allows developers to focus on building their core application functionality rather than spending time and resources building and maintaining infrastructure, APIs, and human interfaces that aren’t unique to any application.
You can leverage existing open-source solutions or opt for a ready-made out-of-the-box solution. You can read a more detailed discussion on the decision of building vs buying when it comes to authorization here.
What should an authorization as a service solution provide?
If you decide to go with an authorization-as-a -service provider, here's a quick list of considerations you should take into account when deciding which solution to pick:
Compatibility: Ensure compatibility with existing systems and infrastructure (Like your cloud environment, programming language, data sources, etc.). Make sure that the transition to the new solution can be fast, yet gradual.
Latency and Locality: Choose a solution considering response times and avoid relying solely on remote querying.
Scalability: Evaluate a solution's ability to handle growth and complex policies or structures.
Security and Compliance: Prioritize cybersecurity, data protection, and avoiding increased attack surface. Ask your provider how they intend to work with your sensitive data for authorization.
Ease of Use: Choose a user-friendly solution that provides interfaces for creating and managing authorization policies.
Support: Ensure reliable customer support and quick response times to address any questions or issues.
A more detailed explanation of all the factors to consider when choosing an authorization service can be found here.
What authorization-as-a-service options are out there?
There is no one-size-fits-all approach to authorization. Each application has its unique requirements, and it’s important to get accustomed to the different solution approaches out there before making a decision. In general, authorization services can be divided into two main categories: Policy As Code solutions, and graph-based solutions.
Graph vs. Code-Based Authorization in a Nutshell:
Policy-as-code authorization utilizes code to define authorization policies, facilitating their modification and offering a higher degree of flexibility, effectively handling complex rules and relationships. Graph-based authorization systems employ a graphical representation to illustrate relationships between users and resources and excel at mapping hierarchies and nested relationships. To learn more about the choice between Graph-Based Authorization and Code Based Authorization check out this article.
Here is a quick list of authorization-as-a-service options:
Open Policy Agent (OPA)
OPA is an open-source policy engine for controlling access to systems and resources.
It uses a high-level declarative language called Rego to define policies and evaluate complex authorization rules. You can read a detailed introduction to OPA here.
OPA has gained significant industry adoption and is backed by a thriving community, making it a reliable choice for building robust and fine-grained authorization services.
AWS Cedar is a new open-source policy-as-code language developed by AWS to streamline IAM management and access control. It introduces a structured and scalable approach to managing permissions, making it a game-changer for application-level permissions. A detailed guide to building RBAC with Cedar is available here.
Permit.io provides an integration with the Cedar policy language, allowing users to generate Cedar code through their UI.
You can read an in-depth comparison between OPA and Cedar here.
Zanzibar serves as Google's gatekeeper for access control and is renowned for its distributed, scalable, and consistent architecture. Underpinning Zanzibar is a graph data model and a distributed consensus algorithm ensuring consistent authorization decisions across the board.
AuthZ’s SpiceDB is a mature open-source graph-based authorization system. Extending beyond the original specifications of Zanzibar, SpiceDB introduces features such as Caveats and adopts the role of a permissions database, emphasizing its centrality in the authorization domain.
Scaling the deployment of your policy engine of choice for policy evaluation in production can be challenging.
While policy engines provide the necessary building blocks for defining policies and evaluating decisions, deploying them with your application at scale requires a solution. This is where OPAL comes in. Supporting both Cedar and OPA, OPAL serves as an administration layer that simplifies the deployment of your policy engine of choice and ensures seamless scalability.
With OPAL, you can effortlessly keep your policy configuration up to date across all deployed policy engines, ensuring consistency and accuracy. It also guarantees that the data used for evaluation remains current, facilitating precise policy enforcement. OPAL's configuration-as-code approach simplifies the deployment process by providing a centralized and easily manageable configuration.
While OPA, Cedar, and Google Zanzibar provide us with the ability to unify all policies in a single service, take on the role of policy decision-making and enforcement from the app’s services, and manage policy as code/graph, they lack one key functionality:
The ability to create, manage and enforce policies in a way anyone in your organization can use.
Normally, creating and managing your application’s authorization policies could only be done through complex R&D work and steep learning curves (e.g. writing Rego or Cedar code). This creates a situation where developers become bottlenecks in your app’s permission management, other stakeholders are locked out of the conversation, and your customers are left without the flexibility they require. All of these manifest as an unending stream of feature requests.
The solution is implementing and managing your policies with a simple no-code UI which makes permission management accessible to other stakeholders. This can be achieved by using Permit, as it allows you to manage policy-as-code with a no-code UI or API, supporting both OPA and Cedar. Permit generates code for RBAC, ABAC, and ReBAC, which you can edit, add to, and manage via GitOps.
Want to learn more about Authorization? Join our Slack community, where there are hundreds of devs building and implementing authorization.