OPA : Zanzibar :: SOAP : REST?
Apr 18th, 2023
Back in the early 2000’s, I led Microsoft’s XML Web Services team. We were building a new protocol stack that could be used to create interoperable web services, with bindings to every programming language. Acronyms like SOAP, WSDL, and UDDI were all the rage.
We partnered with the big platform companies of the time - IBM, BEA, Sun, and others. We had big ambitions - we wrote specs for layering security, reliable messaging, federation, and even transactions on top of SOAP, collectively known as “WS-*”. The standards organizations of the time, W3C and OASIS, blessed the stack as the definitive way to build web APIs.
It was a massive failure.
SOAP vs REST
Turns out, the web already had a protocol - HTTP. Not just a transport, but a protocol that modeled interactions with resources using a fixed set of verbs - GET, PUT, POST, DELETE. The protocol turned out to be well-defined enough that you didn’t need to invent a whole lot more in order to get interoperable web services.
WS-* became derisively known as WS-DeathStar. It was considered a “big company thing” and the companies that actually built web APIs turned to REST. Simplicity won over complexity.
Having had a front-row seat to this show, those painful lessons are still top of mind. I tend to look for analogies to the past, lest I am doomed to repeat the same mistakes.
There are two emerging ecosystems in the space of cloud-native, fine-grained authorization: Open Policy Agent and Zanzibar.
Open Policy Agent
OPA is an open source project that defines a language (Rego) for expressing authorization rules, and an engine for evaluating those rules. The Cloud Native Computing Foundation, the closest thing we have to a “standards body” in the cloud-native world, has blessed OPA as a “graduated project.” It’s the most widely adopted system for cloud-native authorization, in domains such as Kubernetes admission control and enforcing policy over configuration files.
Technically, OPA and Rego are flexible enough to define any type of authorization model - RBAC, ABAC, or even ReBAC. But that flexibility means that Rego has no “opinions:” you have to create your authorization model from first principles. And the learning curve for Rego is steep.
This feels alot like SOAP, which was flexible enough to define any type of protocol interaction (including a REST-style protocol). But every protocol needed to be described (in a language called WSDL) so that language-specific tooling could create a binding to that protocol. Generality comes at the cost of complexity.
Zanzibar is Google’s internal authorization system for Google Drive, Calendar, Cloud, and many other internal systems. Google published a paper on it in 2019, which inspired around a dozen open source implementations, most notably SpiceDB and OpenFGA.
Unlike OPA, the Zanzibar paper describes an opinionated authorization model: objects (e.g. folders or documents) have relationships (e.g. owner or viewer) to subjects (e.g. users or groups). Determining whether a user has a permission on an object means walking this graph to find a path between that user and the object. This is known as “relationship-based access control” or ReBAC.
At first blush, this feels alot like REST: an opinionated model that fits a surprisingly large set of use-cases. But there are also some important differences that strain the analogy.
Is Zanzibar really like REST?
Zanzibar is certainly opinionated, but unlike REST, it’s not a protocol, nor even a specification of any kind. It’s a paper that describes a set of ideas, with many different interpretations and implementations. Each implementation has its own schema language to describe objects and their relationships. Each has its own set of gRPC and/or REST APIs for adding relations and evaluating queries.
Indeed, the Zanzibar ecosystem would greatly benefit from some commonality and re-use across implementations. That may erode some differentiation in the short term, but will create a rising tide that will lift all boats, much like SQL92 in its day did for the RDBMS market.
Ironically, since OPA is a single OSS implementation, it has actually solved these problems: there is a well-defined query API for evaluating authorization rules, a well-specified language for writing those rules, a standard way to express decision logs, and extensibility points for vendors to add features.
SOAP vs REST, revisited
Did REST kill off SOAP? Well, mostly. But what really happened is that the best ideas from the SOAP world got absorbed by the REST “stack.” For example, the idea of a description language (WSDL) found its way into the REST world in the form of Swagger and later OpenAPI.
We also see the fingerprints of SOAP all over the standard identity protocols we take for granted: WS-Federation and SAML are still in use today to provide single sign-on between enterprise identity systems and SaaS products. And OAuth2 was largely inspired by these protocols.
Is it really OPA vs Zanzibar?
SOAP and REST were competing approaches for creating web APIs. REST won but subsumed the best ideas from SOAP.
OPA and Zanzibar are also competing for mindshare in cloud-native authorization. But many of their ideas are complementary. For example:
- OPA desperately needs some opinions. Zanzibar has some. Could we bring the Zanzibar graph model to OPA? Can we flatten the Rego learning curve by making it trivial to build Zanzibar-style policies?
- Zanzibar doesn’t specify a standard protocol, schema language, or decision log format. OPA does. Can we get together as an industry and define those? Is there something to borrow from OPA here?
Topaz: OPA + Zanzibar
These are the type of questions that motivated us to build the Topaz open-source authorization project. We tried to combine the best ideas from both ecosystems:
Leverage OPA "standards". Topaz embeds OPA as the decision engine, to leverage its standard query protocol, policy language, decision log format, etc. We’ll make a bold statement: the world doesn’t need more policy languages, it needs less!
Built-in Zanzibar directory. We added a set of built-in functions, such as
check_relation, that implement Zanzibar’s graph traversal over a Zanzibar-style subject/relationship/object store. Policies can be as simple as delegating to one of these check functions. But they can also add ABAC-style rules, which make it easy to combine authorization styles. So you can “pay as you go” instead of having to learn all of Rego, all at once.
Simple, self-contained. Carrying the “simplicity wins” lesson, Topaz includes everything you need to be used completely standalone, as a single 24mb container.
Composable. Carrying the lesson of composability and extensibility, Topaz defines a gRPC contract that can be implemented over any store - for example, a relational database. This contract can also be used to bridge between Topaz and existing Zanzibar implementations, such as OpenFGA or SpiceDB.
What's holding us back?
Cloud-native authorization is still just getting started. We like Topaz, but we don’t claim that it solves all of the world’s authorization problems. Users and vendors would all benefit if we had some common things:
- A standard language for describing the authorization model, and a specification for how the model is enforced. Since most implementations are in Golang, could there even be a single OSS package that is common across implementations?
- Standard gRPC / REST contracts for evaluating graph traversals and managing tuples. The power of common protocols like OAuth2 is that they make it easy to build common libraries on top.
- Standard decision log format for expressing the results of decisions. Perhaps not as urgent, but it would unlock the ability to define how authorization “plugs into” compliance frameworks, and how to automate gathering evidence.
Let's stop building authorization snowflakes
One thing we all agree on is that it’s time for authorization to go from “everyone builds their own snowflake” to “we have some common patterns and software so that people don’t need to reinvent the wheel.”
Developers ought to select the cloud-native authorization system that best suits their use-cases, and save a bunch of time, effort, and maintenance nightmares that come from rolling your own.
OSS projects and vendors should work to standardize some foundational aspects of cloud-native authorization, such as schema language and protocol. We’ll all benefit.