What it is
The authorization layer most multi-user SpacetimeDB modules end up writing by hand. You define roles as sets of permissions, with wildcards (doc.*) and inheritance, and grant them to identities on a scope. Scopes form a tree (organisation → project → document), and a grant flows down to everything below it. Grants can expire, invite links hand out a role, and every change lands in an audit log.
Nobody can grant more than they hold, so there's no privilege escalation, even through invites or role edits.
Where it fits
- Use it any time more than one person shares data and they shouldn't all see or change everything: team workspaces, shared documents, game guilds and clans, moderation tools, admin panels.
- It replaces the usual
is_adminbooleans and per-table owner checks with one model you can query and audit.
How it works
Mount it with schema({ ..., authz }), then call authz.require(ctx.as.authz, 'doc.write', doc.scopeId) at the top of any reducer. It throws, rolling back the transaction, when the caller lacks the permission.
Reads are protected too. The module materialises what each client may see, so you add row-level-security rules with authz.rlsFor('doc', 'scope_id', 'doc.read', 'authz'), and clients only receive rows they're allowed to read.
Bootstrap the first admin and your roles in init. Rust and C# drop-in versions share the same schema, so one client works with all three.

