by David Brossard, Sr. Director Identity, Product Management — Salesforce
A few months ago, just as summer was getting underway, I had the privilege and honor to speak at Identiverse on the latest trends in authorization (you can watch a recording here and you can glance through the slides here). The talk served as an update to an article I had written in 2018 on the state of authorization. While there is a clear consensus on what authentication is and does, the waters are a little muddier when it comes to authorization. What is it? Where does it begin? End? And why is it so hard to pin down? What are the current efforts in the standards community and the industry to address authorization? This article aims to address these points.
One of the problems with authorization is that it can be used to describe many needs and technologies. The term itself is abused. Think for instance about HTTP 401 Unauthorized. Does it mean you didn’t have the right authorization? No, it means your authentication failed. So, why is it called unauthorized? Just a misnomer. Similarly, OAuth stands for Open Authorization. Yet OAuth is mainly about access delegation (I grant a given service X controlled access to my data on another service Y) and addressing the password anti-pattern. So let’s level-set here and define what authorization truly is in the broadest possible sense:
“Authorization is about granting or denying an entity access to another entity.”
In the presentation I gave in June, I wrote that:
- Authentication confirms that users are who they say they are.
- Authorization gives those users permission to access a resource.
More broadly, authentication is about proving a claim about someone or something. Usually it’s a person’s identity. But it could also be an attribute of that person e.g. their date of birth.
Authorization is the process of granting (or denying) someone or something access to something else. Authorization needs to consider what we know about the requestor and the requested item before granting access.
The challenge is that over the past 15 years there hasn’t been one major model, standard, or framework to address authorization. Unlike SAML which has tackled SSO, there hasn’t been one turnkey solution yet. But The Times They Are a-Changin’ and it’s time to revisit the space.
Requirements for an Authorization Framework
Before we look into existing solutions, let’s look into requirements. Basic ones aside (e.g. consistency or performance), there are three fundamental requirements any authorization model or framework should address:
- Configurable: you need to be able to change your authorization without having to code your application from scratch. It should be possible to reuse the same framework from one application to another.
- Future-proof: your authorization framework should be capable of adapting to new requirements. If a new legislation or business need comes into play (e.g. GDPR) then the authorization framework should be able to adapt.
- Auditable: your authorization configuration (artifacts) should be understandable by the audit teams. Humans should be able to ask both (a) what did happen and (b) what can or may happen.
In addition, authorization needs to reach out from the identity realm to extend to other dimensions. One issue with models like RBAC or standards like OAuth is that they are all identity-centric. Yet, an effective authorization solution needs to consider not only the requestor’s identity but also the targeted resource and its attributes as well as the context of the interaction. This leads us to the Venn diagram of Authorization:
Authorization, properly defined, should reside at the intersection of all three dimensions: identity, entity, and context.
Types of Authorization
I’m often asked what the different kinds of authorization are. I usually break things down into three categories:
- Functional authorization: you could ask whether a user, as a whole, can print. This is fundamental when generating scopes, claims, or maybe just rendering a UI.
- Transactional authorization: can a specific user do a specific action on a specific item e.g. can Alice view account 123? This is nearly always a yes/no (binary) question. Transactional authorization typically occurs in API calls or business processes.
- Data-centric authorization: sometimes you want to select an entire swath of data (an unknown number of items) and asking yes/no questions is either not possible (for we don’t know what there is) or doesn’t scale (for there are millions of records). In that case, we need an authorization framework capable of reversing queries (flip questions). This is data-centric authorization. Data-centric authorization occurs when retrieving data from databases or Big Data systems (anything from traditional RDBMs to systems like Snowflake). To do so, your authorization language’s syntax needs to be ‘reversible’. Lea Kissner of Twitter calls it reverse-indexable. Axiomatics’ Chief Product Officer, Pablo Giambiagi calls it Reverse Query. And OPA’s co-founder, Torin Sandall calls it partial evaluation.
Who Defines Authorization?
There are two main sources for authorization:
- The resource or data owner: I, the owner of the data, decide who can access my data. This is exactly the sort of authorization that takes place when I share a Google Doc with a coworker.
- The enterprise: as the data steward and the owner of the services, the enterprise can determine who can access which services and data. In the previous example, my employer can choose to add authorization checks. For instance, the employee can only share with other employees but not outside the enterprise. Note that the enterprise might have different drivers such as legal, compliance, or merely business.
When do we Enforce Authorization?
There are two ways authorization can be enforced:
- At design-time: in traditional identity-centric authorization models, authorization is usually defined when the user is defined, created, or updated. We assign those users groups, roles, and permissions either directly or via profiles. The rest of the authorization is devolved to the application code.
- At runtime: if we are to consider contextual information e.g. time of day or a requestor’s geolocation and if the authorization is to be decoupled from the application, then it is necessary to enforce authorization at runtime.
Now that we’ve looked at the requirements and traits of a comprehensive authorization framework, let’s discuss existing approaches.
The Current State of the Art
Models, Standards, and Frameworks
When authorization is being discussed things like RBAC, ABAC, XACML, and OPA come to mind. These are not all equal and it’s worth grouping them into one of three categories:
- Model: abstract approach to implementing authorization e.g. ACL, RBAC, and ABAC
- Standard: a formally approved set of specifications that define how to address authorization e.g. SAML, XACML, OAuth…
- Framework: a technical implementation that handles authorization without being a standard itself e.g. Ruby cancancan, OPA, or Oso’s Polar.
With this in mind, let’s charter the land of authorization. In my Identiverse presentation, I came up with the following (incomplete) diagram and timeline.
In the first category, we have 3 main models: ACL, RBAC, and ABAC. There are occasionally other acronyms that pop up e.g. PBAC, GBAC, or ReBAC (policy-based, graph-based and relationship-based) but these tend to be analogous to ABAC.
While ACLs can be extremely fine-grained (to the point of assigning a specific user to a specific item), it is usually too tightly coupled with the applications you want to protect and its management does not scale well.
RBAC addresses the management scale issues of ACLs but, given it is identity-centric, falls short of allowing for contextual, runtime authorization.
ABAC addresses the limitations of RBAC and introduces policies as a means to define authorization rather than roles. However, the governance becomes more arduous. Most of the latest innovations in authorization (Authzed, Oso HQ, Open Policy Agent, and ALFA) are all to some degree ABAC. They use a policy language (or in Authzed’s case a schema language on top of Zanzibar’s configuration language) to express authorization.
The following diagram summarizes ABAC’s architecture and flow.
- PEP: Policy Enforcement Point: this is how applications are integrated into the ABAC architecture. Example PEPs include API gateways, annotations, and proxies
- PDP: Policy Decision Point (the “engine”): the PDP evaluates policies and generates decisions
- PIP: Policy Information Point. PIPs allow the PDP to query data sources for attribute values
- PAP: Policy Administration Point where policies are managed (defined, governed, audited…)
Identity-derived Standards (RBAC)
SAML, OAuth, and all its derivatives such as UMA, GNAP, Rich Authorization Requests (RAR), and JWT access tokens do tackle authorization to some degree. But, as noted previously, they are identity-centric and leave out the context part. Additionally, they are not policy-driven which means they can be harder to manage.
That being said, User-Managed Access (UMA) does fill the authorization gap around consent management. UMA can be used to collect a data owner’s wishes. That information can then be used in other standards and frameworks (e.g. XACML or ALFA).
Rich Authorization Requests (RAR) are also a bridge between the identity side and the authorization side. With RAR, full authorization decisions can be delegated to a decision engine (e.g. a Policy Decision Point).
JWT AT can also be used as the bearer of authorization decisions inside of the access token and as the source of attributes or claims to be used in an authorization decision.
Alone, these standards will suffer from the same woes RBAC suffers from. But used in conjunction with ABAC approaches, they become invaluable.
Standards that Implement ABAC
There are 2 official standards that implement ABAC today: XACML and ALFA. XACML (the eXtensible Access Control Markup Language) has been around since 2001 and is to authorization what SAML is to federation and SSO. They are both part of OASIS’ family of standards. XACML has had some success especially in the era of XML gateways (in the pre API days) but its syntax (XML-based) has made it hard on developers.
ALFA (the Abbreviated Language for Authorization) addresses the syntax aspect of XACML. It is easier for developers to write in ALFA.
XACML and ALFA still lack massive adoption and part of the challenge is that both languages (which are interoperable) are too generic, too broad. This makes it harder on developers and business users. Additionally, XACML and ALFA require that attributes be defined. This is true of any ABAC-like system and it adds an extra burden on the framework adopters. What are those attributes? Who defines them? Who governs them? How are their values retrieved? This is where RBAC is simpler: all attributes are identity attributes and are stored in the “one and only” identity store.
Beyond Standards, Authorization Frameworks Abound
I’d like to start this section with this little xkcd cartoon. When there are too many standards, define a new one. This is, in a way, what’s happened in the past 5 years. In spite of XACML and ALFA, we have seen the rise of Open Policy Agent and its language Rego as well as Oso HQ and its language Polar. Google released Zanzibar (a framework to manage permissions at scale) and several companies (Authzed and Auth0 to name a couple) are building management solutions on top of Zanzibar.
Open Policy Agent
Although I peg them as a framework, they could be considered as a standard given they are part of the CNCF family. OPA follows the same architecture as XACML and ALFA. OPA has a large ecosystem of enforcement points making it easy to adopt OPA especially in the Kubernetes and microservices world. The language, Rego, is based on Datalog. Its syntax is simple enough that it can be handwritten by a developer. However it lacks the scaffolding and structure that come with ALFA or XACML. In addition, Rego can do data manipulation which can be both a good thing and a bad one as it blurs the lines between what should be in a policy (the rules) and what shouldn’t (the data massaging). There are several companies such as Styra who aim to address the management aspect of OPA and Rego.
The Oso authorization library uses the Polar programming language to express authorization logic and policies. Like XACML and ALFA, it is a purely declarative language. Polar combines together the definition of facts e.g.
# father(x, y) ⇒ y is the father of x.
With rules e.g.
allow(“Zora”, “read”, “document-1”) if 1 = 0;
Because Polar mixes both the definition of the model through relationships and the definition of the authorization rules, it steps a little bit outside the boundaries of ABAC and into “ReBAC”. Graph-based authorization models go down that path as well. In the long run, it might make it harder to manage such policies.
Zanzibar provides a uniform data model and configuration language for expressing a wide range of access control policies from hundreds of client services at Google, including Calendar, Cloud, Drive, Maps, Photos, and YouTube. (source). Zanzibar is still ultimately ACL-based. It stores access control lists (ACLs) and performs authorization checks based on those stored ACLs. It acts as a framework on top of ACLs across all of Google’s services (originally). Zanzibar’s goals were not (originally) fine-grained authorization as defined in NIST’s ABAC. Rather, Zanzibar’s goal is to make sure authorization is consistently defined and coherently enforced across all of Google’s distributed services at scale.
From a ‘language’ perspective, Zanzibar uses namespaces, relations, usersets, and tuples. It also muddies the waters between what is truly policy (A user can do X) and definitions (A is the father of B).
The authorization world is growing faster than ever: the # of new startups is a homage to its vibrance. Yes, it pains me to write as such but XACML’s XML syntax is dead. However, in good old Monty Python “I’m not dead yet” fashion, XACML isn’t. In fact, XACML, ALFA, and OPA are essentially variations of the same model, ABAC. Graph-based approaches such as Nulli’s, Oso’s Polar, or Authzed are worth keeping an eye on. I like to keep things clean and as such I prefer ALFA (but I’m also biased). Application and infrastructure vendors (Azure, AWS, SaaS, app frameworks) will keep offering their own approaches. AWS’s IAM is a great example of ABAC using tags and policies (attached to users, objects).
What matters above all else is the ability to easily author, manage, enforce, and audit your policies. This might mean that the true answer to authorization may not so much reside in a single standard or language. It might well reside in the governance layer. And in that space, it may be worth looking into the Identity Query Language (IDQL), a new standard for identity and access policy orchestration across distributed and multi-cloud environments. My former colleague and friend, Gerry Gebel (Strata) spoke on that very topic at the European Identity Conference this past September.
And since you made it this far…
Does it have to be a standard? That’s a good question and I think the short answer is no. There are always benefits to standards (avoid vendor lock-in). In IAM, the biggest benefit has been interoperability. In my role at Salesforce, I am grateful for SAML and OpenID Connect as it makes it easy to integrate Salesforce with many identity providers. But when it comes to authorization, the need for interoperability is not as important. What the policies are written in does not impact how an app is integrated with the policy engine. The need for interoperability is therefore on the request/response side only. Make sure you choose a framework or standard that has a rich ecosystem of integrations. OPA and ALFA both provide integrations.
- Authorization in software – an Auth0-curated podcast
- Identity Unlocked – a podcast by Vittorio Bertocci
- Guide to Attribute Based Access Control (ABAC) Definition and Considerations
- Role Based Access Control
- OASIS XACML
- ALFA – Abbreviated Language for Authorization
- Open Policy Agent’s Rego
- OSO HQ’s Polar authorization language
- ABAC for AWS
- Ping Identity’s Essential OAuth Primer
- Authzed Demo
- Zanzibar: Google’s Consistent, Global Authorization System
- Authorization is the next big technical challenge