SpiceDB Schema Examples: Browse Real Authorization Schemas | AuthZed
Base Layer EP 03: Spencer Kimball on Governance Is the Real Blocker
SpiceDB Schema Fundamentals
What goes into a SpiceDB schema
A SpiceDB schema declares the object types in your application, the relationships between them, and the permissions those relationships grant. It's how you describe your authorization model in a Zanzibar-style permission system. Four building blocks do most of the work:
definition: an object type.user,document,organization,repository. Subjects and resources are both definitions.relation: a typed link between two objects.writer: usersays "a document can have writers, and they are users." Relations can accept subject sets too, liketeam#member, which means "the members of a team."permission: a computed boolean expressed over relations using union (+), intersection (&), exclusion (-), and arrow (->) operators.permission view = reader + edit: anyone withreaderor anyone who canedit.caveat: a CEL expression evaluated at check time using attributes supplied with the request: time windows, IP allowlists, rate limits. This is how you mix attribute-based logic into relationship-based authorization.
Beyond those four, two operators show up everywhere worth recognizing: subject_type#relation lets a relation reference the result of another relation (subject sets and sub-groups), and the arrow operatorrelation->permission walks the graph ("the admins of the owning organization").
How to write your first schema
- Start with the resources. List the things in your product users act on: documents, repositories, projects, features. Each becomes a
definition. - Add the subject types. Almost every schema has
definition user {}. If you have groups, teams, or organizations, define those too. - Model the verbs. What can a user do? Read, write, delete, manage billing? Each verb is a
permissionon the resource. - Map verbs to relations. For each permission, decide who has it. Direct readers? Members of the owning organization? Add the relations and compose them with the permission operators.
- Iterate in the playground. Write a few sample relationships and assertions, then refine. The SpiceDB Playground lets you experiment without standing up infrastructure.
Evolving a schema in production
Schemas are not write-once. As your product grows, your authorization model grows with it: new resource types, new roles, new caveats. SpiceDB is designed to make these changes safe.
- Additive changes are free. New definitions, new relations on existing definitions, and new permissions can ship at any time. They don't affect existing checks. Apply with
zed schema writeor theWriteSchemaAPI. - Renames need migration. Renaming a relation breaks existing relationships. Add the new name, dual-write, migrate readers, then remove the old name. The schema evolution guide walks through the pattern.
- Removing a relation is a breaking change. Drop the references in permissions first, then drop the relation. SpiceDB will reject writes that target a non-existent relation, so removing it cuts off new writes immediately while old data lingers until you clean it up.
- Caveats can be added incrementally. A new caveat alongside an existing direct relation keeps the unconditional path working. Turn caveat-required only when you're ready.
- Validation files are your safety net. Pair every schema change with assertions (in YAML next to the schema, just like the examples above) and run them in CI before you deploy. The same files the playground uses are machine-checkable.
Patterns worth knowing
- Subject sets (
team#member): let you grant access to a group of users rather than enumerating them individually. - Wildcard subjects (
user:*): public access without a row per user. - Synthetic relations: a permission used purely as an intermediate computation, like the
project_comment_deleterpermission in the User-defined Roles example. - Arrow for tenancy (
organization->admin): inherit access from a parent object so you don't have to re-grant on every resource. - Exclusion (
-): remove a subject set from a permission ("everyone except billing managers").
Frequently asked questions
Where do these example schemas come from?
How do I run one of these schemas locally?
What's the difference between a relation and a permission?
Can I mix attribute-based and relationship-based access control?
How do I evolve a schema without breaking production?
Where can I learn more about modeling permissions?
Build authorization with confidence.
AuthZed is the team behind SpiceDB. Get production-grade fine-grained permissions for your application.