Zanzibar Relationship Checks
Zanzibar (from Google's 2019 paper of the same name) models authorization as a graph of relation tuples. Each tuple has the form object#relation@subject — for example document:readme#editor@user:alice reads as "alice is an editor of document readme". A check then asks "does a path exist in the relation graph from this subject to this object under this relation, given the schema's rewrites?"
Use Zanzibar when access is driven by hierarchy and relationships: folders containing files, teams owning projects, organizations containing workspaces. Permission inheritance (folder editors can edit the folder's files) and shared access (all members of a team can view a document) are natural in this model and awkward in RBAC.
POST /api/v1/zanzibar/check
How Zanzibar Checks Work
RBAC asks "does this user have permission X?" — a flat yes/no against a role set. Zanzibar asks "is this user related to this object through this relation?" — and the engine walks the graph to decide.
During a check, LumoAuth:
- Looks up direct tuples that match
object#relation@subject. - Follows userset rewrites in the schema: for example, if
editorimpliesviewer, aneditortuple also satisfies aviewercheck. - Follows computed usersets across relations: for example, viewers of a parent folder become viewers of its documents.
- Returns
allowed: trueif any path is found, otherwisefalse.
A companion expand operation can return the full tree of subjects that satisfy a given object#relation, which is useful for audit and UI rendering.
Request Format
| Field | Type | Required | Description |
|---|---|---|---|
object | string | Yes | Resource being accessed (namespace:id) |
relation | string | Yes | Type of access (e.g., viewer, editor, owner) |
user | string | Yes | Subject (namespace:id or namespace:id#relation userset) |
Basic Example
curl -X POST https://api.example.com/api/v1/zanzibar/check \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"object": "document:annual-report",
"relation": "editor",
"user": "user:alice"
}'
{
"allowed": true,
"object": "document:annual-report",
"relation": "editor",
"user": "user:alice"
}
Understanding the Format
Objects
Objects are the resources in your system, named namespace:id.
| Example | Meaning |
|---|---|
document:readme | A document with ID "readme" |
folder:projects | A folder named "projects" |
organization:acme | Organization "acme" |
repository:myapp | A repository named "myapp" |
Relations
A relation is the kind of edge between an object and a subject. Relation names are defined per namespace in the schema.
| Relation | Typical Use | Usually Implies |
|---|---|---|
owner | Full control over a resource | editor, viewer |
editor | Can modify a resource | viewer |
viewer | Read-only access | - |
member | Belongs to a group or org | viewer (of group resources) |
admin | Administrative access | owner, member |
parent | Hierarchical containment | Permission inheritance |
Subjects
A subject is either a concrete identity or a userset — a reference to every entity holding a given relation on another object.
| Format | Example | Meaning |
|---|---|---|
namespace:id | user:alice | A specific user |
namespace:id#relation | team:engineering#member | All members of the engineering team |
namespace:id#relation | organization:acme#admin | All admins of the Acme org |
Userset Subjects
Userset subjects let you attach an entire group to an object in a single tuple. The check walks into the userset when evaluating.
Given tuples like team:engineering#member@user:bob and document:api-docs#viewer@team:engineering#member, the following check returns allowed: true:
curl -X POST https://api.example.com/api/v1/zanzibar/check \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"object": "document:api-docs",
"relation": "viewer",
"user": "user:bob"
}'
The engine reasons:
- Bob is a
memberofteam:engineering. team:engineering#memberis aviewerofdocument:api-docs.- Therefore Bob is a
viewerofdocument:api-docs.
Examples
Document Sharing (Google Docs Style)
# Can Carol view the Q4 report?
curl -X POST https://api.example.com/api/v1/zanzibar/check \
-d '{"object": "document:q4-report", "relation": "viewer", "user": "user:carol"}'
# Result: allowed: true (Carol is on finance team, which has viewer access)
# Can Carol edit the Q4 report?
curl -X POST https://api.example.com/api/v1/zanzibar/check \
-d '{"object": "document:q4-report", "relation": "editor", "user": "user:carol"}'
# Result: allowed: false (Carol only has view access via team membership)
Folder Hierarchy
# Can Alice view the readme?
curl -X POST https://api.example.com/api/v1/zanzibar/check \
-d '{"object": "document:readme", "relation": "viewer", "user": "user:alice"}'
# Result: allowed: true (Alice owns the parent folder)
GitHub-Style Repository Access
# Org structure
organization:acme#admin@user:ceo
organization:acme#member@user:developer
# Team in org
team:platform#parent@organization:acme
team:platform#member@user:developer
# Repo owned by team
repository:api-service#owner@team:platform#member
# Schema: org admins are admins of all repos
# Schema: team members who own a repo are maintainers
Comparison: Zanzibar vs RBAC
| Aspect | RBAC Check | Zanzibar Check |
|---|---|---|
| Question | Does user have permission? | Does user have relation to object? |
| Example | document.edit | document:123#editor@user:456 |
| Resource aware | No (global permission) | Yes (specific resource) |
| Inheritance | Role hierarchy only | Object + relation hierarchy |
| Best for | Admin features, global actions | Shared resources, hierarchies |
Related
- Authorization Overview — model comparison and when to choose Zanzibar.
- Permission Checks — RBAC-style check endpoints.