Concepts
Fine-grained authorization
A real Zanzibar-style tuple store with direct + userset traversal, ready for relation-based authz.
Authio’s FGA service answers questions like “does Alice have viewer permission on document:doc-1?” It models relationships as tuples in the canonical Zanzibar form:
document:doc-1#viewer@user:alice
group:engineering#member@user:bob
document:doc-1#editor@group:engineering#memberThe first tuple says “Alice is directly a viewer of doc-1.” The third says “every member of group:engineering is an editor of doc-1.” A check for “is Bob an editor of doc-1?” succeeds via userset traversal: doc-1 has editor relation@group:engineering#member, and bob has member relation@group:engineering, transitively granting the editor role.
Write tuples
POST /v1/stores/{store_id}/write
{
"writes": [
{"object":"document:doc-1","relation":"viewer","user":"user:alice"},
{"object":"group:engineering","relation":"member","user":"user:bob"},
{"object":"document:doc-1","relation":"editor","user":"group:engineering#member"}
]
}Check
POST /v1/stores/{store_id}/check
{
"tuple_key": {
"object":"document:doc-1",
"relation":"editor",
"user":"user:bob"
}
}
200 OK
{
"allowed": true,
"resolution": "userset",
"resolution_path": [
"userset(group:engineering#member)",
"direct(group:engineering#member@user:bob)"
]
}What ships today
- Direct tuple matches:
obj#rel@user:X. - Userset references:
obj#rel@type:id#rel, recursively evaluated with depth-cap and visited-set cycle protection. - Per-project stores so checks for one customer can never see another customer’s tuples.
What’s coming
- Computed userset (
relation = otherRelation) and tuple-to-userset (relation = parent.relation) rewrites. - Intersection / difference rewrites.
list_objectsandexpandqueries for UI-side enumeration.- Authorization-model versioning (the table shape is in place now; the evaluator just hasn’t taught itself to honor models beyond direct + userset yet).