SpiceDB Schema
The portal_* SpiceDB schema — definitions, relations, and permissions for Control Plane resources.
Control Plane stores authorization tuples in SpiceDB using the portal_* namespace. The canonical schema lives in the product repo as schema.zed.
Definitions
definition portal_user {}
definition portal_account {
relation owner: portal_user
relation billing_admin: portal_user
relation member: portal_user
permission administer = owner + billing_admin
permission view_billing = administer
permission manage_members = administer
permission read = administer + member
}
definition portal_workspace {
relation account: portal_account
relation owner: portal_user
relation admin: portal_user
relation writer: portal_user
relation member: portal_user
permission administer = owner + admin + account->administer
permission read = administer + writer + member
permission write = administer + writer
permission delete = administer + writer
permission ddl = administer
permission deploy = administer
permission manage_members = administer
}
definition portal_environment {
relation workspace: portal_workspace
relation deployer: portal_user
permission deploy = deployer + workspace->administer
permission read = workspace->read
}Permission inheritance
portal_account.administer
└── portal_workspace.administer (via account->administer)
└── portal_workspace.write / delete / ddl
└── portal_environment.deploy (via workspace->administer)Account owners inherit workspace administration. Workspace writer relations grant data-pillar mutations without full admin.
Write path
After a Postgres transaction commits (membership grant, workspace create, etc.):
- Control Plane writes the SpiceDB tuple via direct gRPC
- On failure, the tuple is enqueued to a DLQ (
spicedb_write_failures) - A background drain loop retries with exponential backoff
- An hourly drift reconciler re-TOUCHes membership tuples as a safety net
Customer data in Dataplane uses a separate schema namespace and optional permission projection at scale.
Schema changes
To add a relation or permission:
- Edit
schema.zedin the Control Plane repo - Push schema to SpiceDB
- Update
app/auth/authorization.pyclosed vocabulary - Migrate existing relationships if needed
- Land schema + code + docs in one change
Related
- ReBAC model — conceptual overview
- Dataplane authz brief — why Control Plane does not use projection
- Architecture decisions — D-003, D-004 summaries