Skip to main content

RBAC permissions

The full action × subject matrix as seeded by server/prisma/seed-permissions.ts. The seed is the source of truth; this page is a transcription. Run tsx prisma/seed-permissions.ts to apply it.

Project scope

roleresourceactionsownOnly
project_ownerannotationcreate / read / update / delete / share / exportno
project_ownersummarycreate / read / update / delete / share / exportno
project_ownerclaimcreate / read / update / delete / share / exportno
project_ownerpersonacreate / read / update / delete / share / exportno
project_ownerworld_statecreate / read / update / delete / share / exportno
project_ownerprojectupdate / delete / manage_membersno
project_managerannotationcreate / read / update / delete / share / exportno
project_managersummarycreate / read / update / delete / share / exportno
project_managerclaimcreate / read / update / delete / share / exportno
project_managerpersonacreate / read / update / delete / share / exportno
project_managerworld_statecreate / read / update / delete / share / exportno
project_managerprojectread / update / manage_membersno
annotatorannotationcreate / read / update / delete / share / exportyes (read excluded)
annotatorsummarycreate / read / update / delete / share / exportyes (read excluded)
annotatorclaimcreate / read / update / delete / share / exportyes (read excluded)
annotatorpersonacreate / read / update / delete / share / exportyes (read excluded)
annotatorworld_statecreate / read / update / delete / share / exportyes (read excluded)
annotatorvideoreadno
annotatorprojectreadno
reviewerannotationread / reviewno
reviewersummaryread / review / exportno
reviewerclaimread / reviewno
reviewerpersonareadno
reviewerworld_statereadno
reviewervideoreadno
reviewerprojectreadno
viewerannotationreadno
viewersummaryreadno
viewerclaimreadno
viewerpersonareadno
viewerworld_statereadno
viewervideoreadno
viewerprojectreadno

annotator writes are own-only: CASL adds the row's ownership column as a condition. Reads are unconditional within the project, so an annotator sees every annotation in their project but can only update their own.

Group scope

roleresourceactionsownOnly
group_ownergroupupdate / delete / manage_membersno
group_ownerprojectcreateno
group_admingroupupdate / manage_membersno
group_adminprojectcreateno
group_membergroupreadno

System scope

The seed leaves the system scope empty under the user role. Every authenticated user gets the baseline ownership rules unconditionally; project / group memberships add to the matrix above. system_admin does not need RolePermission rows; the ability builder short-circuits with can('manage', 'all').

The integration test helper at server/test/integration/_rbac-baseline.ts populates the system scope under the user role with ownOnly: true rows for every content action — this is what tests against multi-user isolation exercise. Production does not seed those rows.

Editing

The matrix is editable at runtime via /api/admin/permissions. Edits flush the per-user ability cache so they take effect on the next request.