zite.permissions.json at the workspace root; every app and workflow enforces them on every zite.* call. Schema → permissions file; evaluation model → Roles & permissions.
A practical file
Managers get full access toDeals; account executives can read and update only their own rows:
builtin:all-team-members role id to grant something to everyone internal.
Gotchas
-
"defaultPolicy": "deny"is what turns roles on. Leave it out and the whole file is inert: every rule above is stored and none is enforced, with no error. This is the single most common way a rule set silently does nothing. -
Table keys are PascalCase.
"Deals", not"deals", even though you call it aszite.deals. A mis-cased key passes validation and then matches nothing, which under deny-by-default locks the table rather than opening it. -
Rules cover external apps too. External and anonymous visitors match
builtin:all-users, notbuiltin:all-team-members, so a file that names only the team-members built-in locks every public visitor out. Scope a public app’s data with a row filter on auserField, and require a session on the workflow:See Auth and Authentication. -
Check filter keys against
.zite/db.ts. An unrecognized key infiltersis dropped rather than raising, so a typo makes the query broader than you wrote. See the database client. -
rowFilterdoes not apply tocreate. A create rule grants the operation outright; enforce constraints on new rows in the workflow. -
You define roles here; a human assigns them on the Members tab. Keep each role’s
idstable across renames so assignments survive. - Administrators and workspace editors bypass all rules when using internal apps.