Getting started with modern authorization

Jan 3rd, 2024

Noa Shavit avatar

Noa Shavit

Authorization

Cloud-native authorization 101

Aserto is a modern authorization platform. We set out to solve authorization. Up until very recently, as an industry we’ve focused almost exclusively on solving authentication, which is now a solved problem. Authorization is far from that.

While there are many methods for authentication (MFA, biometrics, passwordless, etc.) we have identity standards and an interoperable identity fabric. There are no standards or mature external developer services for authorization. Every vendor supports its own protocols and APIs. Every application builds its own permissions and authorizes differently. It’s the wild west.

In this post, we review an organization’s authorization journey, from hard coded logic that is deeply coupled with the application to externalized authorization. Read all about it below or watch this video.

Embedded authorization

An organization’s authorization journey tends to start out by embedding authorization logic into application code. Developers will sprinkle if and switch statements in different places in the code, as needed. And they will continue to do so until authorization code makes up 20% of the application’s code.

The result is authorization logic that is difficult to reason about, audit, and maintain. Every change to the logic will need to be tested and applied to multiple places in the code. But more importantly, there is no central view of all the authorization logic, making it extremely difficult to reason about holistically.

This is the reason that most applications have some form of broken access control vulnerabilities. The OWASP actually found one or more such vulnerabilities in 94% of the apps it tested, propelling this issue to become the #1 vulnerability on the OWASP top 10 list of application vulnerabilities.

So how do organizations tackle the issues that come with embedding authorization into application code? They externalize it.

Externalized authorization

Externalized authorization service- Aserto

Modern authorization is externalized authorization. The first step in externalizing authorization is to extract all the authorization logic out of the application code and make it a separate concern - the domain of an externalized authorization service.

There are two technical approaches to externalizing authorization:

  1. Policy-as-code: authorization logic is expressed in an external policy written in a domain-specific language and treated like any other application artifact. Open Policy Agent (OPA), which is primarily used in infrastructure scenarios (e.g. Kubernetes Admission Control), is a well known example of this approach.
  2. Policy-as-data: access is determined based on a set of fixed rules that are written in terms of relationships between subjects and objects, as well as the tuples (data) that expresses those relationships. Google Zanzibar, the authorization system behind Docs, Drive and other popular Google apps, is the most well known example of a graph-based policy-as-data authorization system.

Both approaches enable fine-grained authorization, where permissions are tied to specific resources.

Following the zero-trust principle of least privilege, a user does not have access to all the resources, but just those they need to perform their function. A developer, for example, will not have access to every ticket in Jira, but just those that are assigned to them/their team. In the same way, a Salesperson will not be able to update all the opportunity records in Salesforce, but just those that they own. These are real-world examples of fine-grained permissions.

The systems that provide this level of control must enable certain functionality, due to the nature of the problem. Read on for the five fundamental functions that any modern authorization service needs to enable.

The five laws of authorization

Here are five key functional requirements to keep in mind when you build/buy an authorization service:

  1. Unified authorization service with a distributed systems architecture: authorization is a cross-cutting concern. It needs to be extracted out of each service, and into a separate concern. Given that authorization is on the critical path of every application request it has to happen in a small number of milliseconds and be 100% available to callers. To this end, the authorization service should be deployed to the edge of the application / service. This often means deploying it as a sidecar, or as a microservice running right next to the application pods. And it leads to an authorization service with a distributed systems architecture.
  2. Fine-grained authorization: gone are the days of overprovisioned roles. Modern applications require resource-level access controls. Adhering to the principle of least privilege means that users have permissions relevant to resources. This way we can ensure users only have access to what they need to perform their function.
  3. Policy-based access control: authorization logic is extracted from code and aggregated in an external policy. The policy is authored in a domain-specific language, like Rego or Cedar, and stored in its own repository where it can be versioned and tagged.
  4. Real-time authorization: eliminating the archaic practice of  standing permissions. Modern applications run real-time access checks prior to providing access. The app shares user and resource context (i.e. who is trying to access what) with the authorization decision engine. The decision engine evaluates that information in the context of the latest policy and relationship data and makes an access decision.
  5. Centralized decision logs: every authorization service needs to provide audit trails. A log of every authorization decision made is a must for compliance, auditability and forensics. In case of a breach, these logs pinpoint the blast radius by providing a trail of every resource the breached identity accessed, as well as those it wasn’t able to access.

Topaz, our open-source authorizer, is based on these principles and combines the best of policy-as-code with policy-as-data. It performs authorizations in ~1ms and supports every authorization model (role-based, attribute-based, relationship-based, policy-based, etc.). And it's falling-off-a-log easy to integrate into your stack, with a complete set of SDKs, quickstarts, and docs. Topaz is a great starting point for organizations that want to test out fine-grained authorization.

Aserto was built on top of Topaz and adds a control plane for easy management of policies, users, attributes, resource and relationship data, and decision logs. Aserto is for when you are ready to fix authorization across the organization. It makes it easy to create a consistent experience across applications and services.

Conclusion

In this post, we describe the common evolution of authorization within organizations, starting from embedding authorization logic within application code and ending with externalized authorization.

Externalized authorization services incorporate five fundamental principles. These include a distributed architecture to enable the low latency and high availability that is required from a service that is on the critical path of every application request. Fine-grained control to enable resource sharing and adhere to the principle of least privilege. Policy-based access management to simplify policy management and governance by decoupling policy from code. Real-time access checks to verify access at the time a request is made, based on the most up-to-date information. And a centralized log of every access decision made, to enable compliance, audits, and forensics.

Topaz is an open-source authorization project that was built based on these principles. It is a great first step into the world of externalized authorization. Be sure to let us know what you think, and join our community on Slack. See you there!

Noa Shavit avatar

Noa Shavit

Head of Marketing