SpiceDB is an open source database system for managing application permissions. It is inspired by Google’s internal authorization as described by the Zanzibar paper. In both systems, relationships between resources and users are stored and queried by applications in order to determine whether or not a user should be allowed to access a resource. Newcomers to SpiceDB often pose the question: how does SpiceDB differ from the paper? We briefly cover each difference in our documentation, but today I’d like to talk about one specific difference: how users are modelled in SpiceDB.
Before jumping into how SpiceDB works, let’s briefly run through how the system at Google functions.
Google has their own user service, GAIA, which provides guarantees to their authorization service, Zanzibar.
Most importantly, GAIA guarantees a globally unique, stable integer for every user or program that interacts with Google’s software.
As an aside, you can find GAIA IDs present in the data Google exchanges during an OAuth flow and occasionally in public-facing URLs for Google products.
The assumption that users can always be represented by a unique integer is pervasive in the design of Zanzibar.
As a result, Zanzibar treats users as a first-class concept.
In their simplest case, relationships take the form of three values:
(resource, relation, user) such as
(document:readme, viewer, 1234567).
When designing SpiceDB, we knew that organizations outside Google often do not have a ubiquitous user system like GAIA. Today, most organizations leverage various Identity Providers that use protocols such as OIDC, SCIM, and SAML in order to bridge their user systems into their applications. However, each organization structures and interacts with their Identity Providers in different ways. This makes it infeasible to assume any details of the authentication system(s) that could simplify the design of SpiceDB.
Ultimately, there were three options we considered: take a hard stance on how users should be represented, build on the lowest common denominator between all of the possible ways that users could be represented, or allow developers to model their own users. Taking a hard stance would limit adoption and potentially require us to build our own Identity system. Building on the lowest common denominator would limit functionality and might not satisfy the requirements of those adopting SpiceDB. Allowing developers to model their own users pushes complexity to the developer, but makes it possible to satisfy any and all of their requirements.
We chose to move forward with the last option: users are not a special case built into SpiceDB, but rather Objects like everything else.
This allows for relationships that take the form of
(resource, relation, subject), such as
(document:readme, viewer, user:1234567).
This might appear very similar to Zanzibar, but allows for interesting ideas like having different types of subjects (e.g. users, personal access tokens, API keys).
What’s more, the freedom to model your own users allows for schemas that are not only singular user types, but a graph of various interrelated types. This can be used implement all kinds of behavior, including making users agnostic to the identity provider or supporting various identity providers simultaneously.
In the example below, we create a top-level user type that owns accounts of various other types: GitHub and LDAP.
By defining the
view permission on documents as
viewer + viewer->owned_account, it allows for checking access not only for the user type, but also directly with GitHub and LDAP accounts.
You can see these checks being exercised in the Assert tab below.
By empowering developers to model their own user types, we’ve created a more flexible system. We believe that this is the proper trade-off for SpiceDB and the natural conclusion if your design goals are to not impose any restrictions on application design or build identity products. While we’ve been using our own custom subject types for the Authzed dashboard, we’re still impressed by some of the designs that have been shared with the community. As more community collaboration occurs, it will be interesting to see what patterns emerge.
Want to learn more about the SpiceDB schema language? You can read the reference documentation, read our previous blog post on allowing all users to have access to a public resource simultaneously, or join Discord to see and discuss what schemas folks are developing.