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#member

The 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_objects and expand queries 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).