Stateless vs Stateful Authorization

Mar 28th, 2025

Omri Gazitt avatar

Omri Gazitt

Authorization

stateless vs stateful

Much like any problem in computer science, an authorization system requires both logic and data. The logic describes rules (how a permission is granted), which operate on data (attributes on subjects, resources, or relationships between them).

At a high level, authorization systems have plenty in common. Every externalized authorization platform offers a way to author the rules, typically using a domain-specific language that is evaluated by an authorization engine.

The biggest difference between authorization systems is in how they deal with data.

Stateless systems

Traditionally, authorization systems separate policy decision points (PDPs), which evaluate policy rules, from policy information points (PIPs), which provide the data used for authorization. Examples of stateless systems include XACML, AWS Cedar, Cerbos, and the typical usage pattern for the Open Policy Agent (OPA). Topaz, which is based on OPA, can also be used as a stateless system.

P*P architecture

In a stateless architecture, there are two ways to bring data to the engine: pass it in as an input as part of the authorization request, or make a call from the PDP to an external information system during the evaluation of the policy.

Passing data as an input

In this architecture, the only purpose of the authorization engine is to evaluate rules over data that is gathered by the caller and passed in when the authorization engine is invoked. This means that the caller, known as the policy enforcement point (PEP), is responsible for gathering all the data from “source-of-truth” systems before it can call the authorization engine.

For example, in OPA, this means passing an input JSON object as part of the call to the OPA engine, and accessing that JSON object in the policy using the input primitive.

The advantage of this architecture is that data is always retrieved from the source, and is therefore guaranteed to be fresh. It also means that there isn’t a need for replicating data in more than one place.

The drawback is that the PEP needs to do the “heavy lifting” of gathering the data from source systems, which increases the burden on the PEP developer, and therefore increases the risk of coding errors, bad inputs, and stale data. Architecturally, this model erodes many of the separation-of-concerns benefits that come from adopting an externalized authorization architecture. It is essentially a “self-attestation” model.

It also means that the overall latency and availability of the authorization process depends on this data gathering “pre-processing”, and may introduce variability in both.

Since authorization is in the critical path of every application request, this architecture may not be ideal for latency-sensitive workloads.

Calling out of the authorization policy

Another pattern employed by stateless systems is to make an HTTP request out of the authorization policy to retrieve a JSON object from the information point. For example, in OPA, this is done using the http.send built-in function.

The advantage of this approach over the previous one is that the caller doesn’t have to do the work of gathering all the input data - that logic can be encapsulated in the policy.

The drawback is that the policy is no longer a simple evaluation over local data - it introduces side-effects and variability in execution, as well as the abovementioned latency and availability issues. Specifically, if a remote data source is non-responsive, the policy must evaluate as a “deny”.

In other words, this approach helps with encapsulation at the cost of complexity, but doesn’t help with the runtime execution issues that are found in the “purely stateless” approach.

Stateful systems

Modern authorization systems focus on providing more state management capabilities than the traditional systems. Notably, systems based on Google’s Zanzibar architecture implement the relationship-based access control (ReBAC) paradigm, which evaluates an authorization model over a set of tuples that define relationships between subjects and objects.

In principle, these tuples can be passed in as inputs (just like the stateless approach), but in practice, every Zanzibar-based system provides primitives for storing these tuples in a local or remote storage layer.

Examples of these systems include OpenFGA, SpiceDB, and Topaz, as well as NGAC-based platforms (which use a full graph model instead of a tuple model).

The advantage of stateful systems is that the caller doesn’t have to worry about bringing the data to the engine at execution time - the data is already accessible to the engine. This means faster and more consistent execution times for the evaluation process.

The tradeoff is that stateful systems must be kept up-to-date by the application and other information systems that contain data relevant to the execution of the policy. For example, if an authorization model utilizes group relationships, and assuming group membership resides in an identity provider or directory, every time a group membership changes, the authorization system must be notified.

In practice this means that the authorization system acts as an “extract database” for the source-of-truth systems that capture group memberships, managerial relationships, and similar data that is used by the authorization policy.

It’s worth noting that OPA, which is based on traditional stateless models, also introduces rudimentary capabilities for storing data (expressed as a JSON document) along with the policy.  This data can be accessed in the policy via the data primitive. However, since the data and the policy are compiled into a single artifact, this mechanism is only useful for data that changes as slowly as the policy does - for example, lookup data. With most application authorization use-cases, policy changes slowly, but data changes rapidly, so this coupling of the data into the policy artifact is awkward.

Taking state further

Stateful ReBAC systems typically only store relationships between subjects and objects, but authorization policies may want to reason about attributes of these subjects and objects in addition to their relationships.

Topaz is a stateful authorization platform that can store both relationships and attributes / properties of objects. Authorization policies can then reason about both of these aspects.

To illustrate the value of this, let’s consider a policy that allows the approval of a claim by an adjuster if that adjuster is the assignee of the claim (a relationship), or in the management chain of that assignee (a transitive relationship), provided that the adjuster’s approval limit (an attribute of the user) exceeds the value of the claim (an attribute of the resource).

In a stateless authorization system, all this data would need to be gathered up front, or by the policy.

In a “vanilla” ReBAC system, the relationships can be stored in the authorization service, but the attributes for the user and resource must be extracted from a data source and passed in as data.

With Topaz, all of this data can be stored uniformly in the authorization store, and the policy to support this scenario is quite straightforward to write.

Topaz combines the best of stateless and stateful systems

Topaz was designed to bring together the best elements of OPA and Zanzibar: it provides a policy layer via the Open Policy Agent, and combines it with a full Zanzibar-based store. The Topaz store is implemented as an embedded database, which offers lightning-fast, sub-millisecond evaluation times using local data.

Just like OPA, Topaz can be used as a stateless system: you can pass input data and make HTTP calls out of the policy. But Topaz shines when you take advantage of its built-in storage model.

Ultimately, Topaz is built to provide choice. Every authorization use-case is different, and sometimes it makes sense to trade off some performance for the simplicity of not having to replicate data out of source-of-truth systems. For other use-cases, the only way to achieve your  latency and availability goals is via a stateful approach.

In Summary

Designing the data architecture of an authorization system is the most important and challenging aspect of authorization. Stateless and stateful systems both have their advantages and tradeoffs. Using a system like Topaz gives you maximum flexibility with respect to which model to use, including hybrid approaches.

We’d love to discuss your authorization challenges! Contact us, join our slack, or schedule a call with one of our engineers.

Omri Gazitt avatar

Omri Gazitt

CEO, Aserto