OPAL + OPA VS XACML
A view of OPAL + OPA as an alternative to XACML
Way back in 2013, various devs were either announcing or debating the death of XACML - yet XACML’s goal to promote a common terminology and interoperability between authorization implementations remains valid, and it still serves as a solid base to describe the structure of authorization architectures.
The IAM landscape, authorization included, has evolved drastically in the past couple of years and allowed for new XACML alternatives to be created. This significant shift was a result of the rising demand for increasingly advanced authorization, which was generated by the growing complexity of applications and their migration to microservices and cloud-native structures. With advancements in technology, the emergence of shift-left and low/no-code developers, and the need for event-driven dynamic authorization - a replacement for XACML had to evolve.
One such XACML alternative is OPA + OPAL. Open Policy Agent (OPA) is an open-source project created as a general-purpose policy engine to serve any policy enforcement requirements that unifies policy enforcement across the stack without being dependent on implementation details. It can be used with any language and network protocol, supports any data type, and evaluates and returns answers quickly. OPA’s policy rules are written in Rego - a high-level declarative (Datalog-like) language. You can find a more detailed introduction to OPA here. It’s important to note that OPA itself only provides an alternative to XACML’s PDP (More on that further). OPA is enhanced by OPAL (Open Policy Administration Layer) - another open-source solution that allows you to easily keep your authorization layer up-to-date in real-time. More information about the project is available here. The combination of OPA and OPAL provides a solid alternative for XACML.
To better understand this alternative, we’ll compare the traditional XACML architecture authorization flow with the one provided by OPA + OPAL and then discuss the differences. It's important to note that while being a primarily Attribute-Based Access Control (ABAC) system XACML can also be used to describe Role-Based Access Control (RBAC) and other models.
A few basic terms to understand the flow:
The architecture of XACML consists of a few different modules that make up the process of making authorization decisions. Let’s take a look at those different parts:
PEP - “Policy Enforcement Point”:
The PEP intercepts a user’s access to a resource, and either grants or denies access to the resource requested by the user. PEPs don't make the decisions; they enforce them.
PEPs can potentially also adjust requests or their results before passing them through (aka data-filtering). Examples of PEPs are in-code control flow (i.e. “if”), middleware, reverse proxies, and API gateways
PDP - “Policy Decision Point”:
The PDP evaluates authorization requests against relevant policies and a data snapshot aggregated from the distributed data layer and makes an authorization decision.
PAP - “Policy Administration Point”:
The PAP is in charge of managing all relevant policies to be used by the PDP.
PIP - “Policy Information Point”:
The PIP is any data source (Internal or external) that contains attributes that are relevant for making policy decisions.
PRP - “Policy Retrieval Point”:
The PAP is the main source of policies - it stores all relevant policies to be used by the PDP, and is managed by the PAP (In OPA it's a bundle-server, and in OPAL this is often a Git repository or an HTTP bundle server).
Traditional XACML Architecture
Let’s start by reviewing the architecture of traditional XACML and its authorization flow:
Everything starts with a user (or automated entity) interacting with an application. The user sends a request to access and perform an action on any sort of resource within the application. Before being submitted to the application logic, the request passes through the PEP. The PEP is in charge of either granting or denying a user’s request for access to the resource.
The PEP translates the user's request into an XACML authorization request. It is important to note that one user request can trigger multiple authorization queries (as it interacts with multiple resources).
To know whether the request should be approved or rejected, the PEP sends the authorization request to the PDP.
The PDP makes make authorization decisions based on pre-configured XACML formatted policies.
The policies are stored in the PRP and are managed by the PAP.
If needed - the PDP queries relevant PIPs per query for any additional relevant information.
The PDP reaches a decision (Permit / Deny / etc.) and returns it to the PEP.
The user is either granted or denied access to the resource by the PEP, based on the PDP’s decision.
OPA + OPAL Architecture
While based on similar principles, OPA and OPAL provide a slightly different authorization model with significant benefits:
The first step is identical to XACML - the user / automated entity sends a request and it passes through the PEP.
The PEP converts the user's request into queries for the PDP (In this case - OPA).
The queries are submitted by the PEP to the PDP (OPA) to know whether the request should be approved or rejected. So far so good - here is where things are a bit different. First of all, OPA stores all relevant policies within its cache. Second - the policies are represented as code (In Rego), unlike XACML where they are represented as configuration (as XML schema).
The PAP (In this case - the OPAL Server) serves a dual function. It both functions as a Policy Administration Point and a Policy Information Administration Point.
4.1 As a Policy Administration Point - The OPAL server is in charge of managing all relevant policies and supplying them to OPA, within the PDP.
Policies are stored as code in a GIT repository (default option, though others exist), which acts as the PRP. The OPAL Server receives policy updates from the PRP and instructs the OPAL clients to update OPAs’ caches accordingly. Every time a change in a policy happens in GIT, it is pulled by the OPAL Server and pushed into OPA’s cache via the OPAL clients which listen to the server (based on topics) and are located next to the OPA instances. By leveraging GIT and policy as code, OPAL allows us to use Gitops best practices (e.g. tests, code-review, benchmarking)
In this manner, OPA always stays up to date with the latest policy changes in real-time without the need for redeployment.
4.2 As a Policy Information Administration Point - the OPAL server informs the OPAL Client within the PDP on changes to data within the PIPs according to selected topics. With the updates to the client, the server sends instructions on how to query the PIPs, and the OPAL Client fetches the data directly from the PIPs (according to the instructions) and updates OPA with the most recent information. As this process is continuous, the information stored in the PDP cache is always up to date with the latest data needed to make access decisions in the most accurate way possible.
The PDP (OPA) reaches a decision (Permit / Deny / etc.) and returns it to the PEP.
Based on the decision made by the PDP (OPA), the PEP either grants or denies the user’s access to the resource.
From the differences in the authorization flow between the traditional XACML and OPA+OPAL, we can note three significant benefits which the latter provides:
OPA (+ OPAL Client)
GIT (Or any other policy source)
As part of the deployment
As part of a query
The OPAL server’s ability to receive updates from GIT (Or any other policy source) keeps OPA up to date with the most recent policies - allowing us to make policy changes on the fly and have them utilized by the PDP with minimal latency. Leveraging policy as code within a GIT repository enables the adoption of configuration as code and Gitops in general.
The OPAL server not only manages the policies themselves, but also the PIPs from which additional data is often required to make a policy decision. The OPAL Client constantly listens to changes in relevant PIPs (Internal or external databases) and uses data fetchers to keep OPA’s cache constantly up to date with the latest information needed to reach an authorization decision. Because this is an ongoing process and not done per query, OPA can have all the relevant information in its cache to make policy decisions even if the PIP is not available - preventing the PDP from making the authorization decision.
While not evident from the authorization flow which we described, it is important to note that policy in Rego is much more accessible and easier to read/maintain than in XACML. Check out this example: (For a more detailed explanation of this example check out this guide)
Same policy side to side - Rego and XACML
The differences between Traditional XACML and OPA+OPAL highlight the drastic changes in the authorization space that occurred in recent years. OPAL’s ability to receive both data and policy updates in real-time allows for the creation of event-driven dynamic authorization. At the same time, OPA provides the ability to define more complex authorization structures fit for microservices and cloud-native structures, and its policy language Rego is easier to read/maintain and provides accessibility to low/no-code developers.
OPAL is a mature open-source project which is already keeping hundreds of policy agents updated in real-time. You can join OPAL’s Slack community to chat with other devs who use OPAL for their projects, contribute to the open-source project, or follow OPAL on Twitter for the latest news and updates.