>

Apply for $700 in starter credits on AuthZed Cloud

[Apply now]

SpiceDB Schema Examples

Real authorization schemas, from a starter document sharing model to a full Google Cloud IAM rewrite. Each one is annotated line by line and ready to copy into the SpiceDB Playground.

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: user says "a document can have writers, and they are users." Relations can accept subject sets too, like team#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 with reader or anyone who can edit.
  • 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 operator relation->permission walks the graph ("the admins of the owning organization").

How to write your first schema

  1. Start with the resources. List the things in your product users act on: documents, repositories, projects, features. Each becomes a definition.
  2. Add the subject types. Almost every schema has definition user {}. If you have groups, teams, or organizations, define those too.
  3. Model the verbs. What can a user do? Read, write, delete, manage billing? Each verb is a permission on the resource.
  4. 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.
  5. 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 write or the WriteSchema API.
  • 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_deleter permission 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

Build authorization with confidence.

AuthZed is the team behind SpiceDB. Get production-grade fine-grained permissions for your application.