Personas
A persona is a versioned bundle of permissions seeded into the roles table (BuiltinRole{key, name, scope_kind, description, permissions, version}, version 1). Bundles are expanded from patterns at import
time, so a typo fails the API at start-up; sync_builtin_roles inserts missing personas and updates
changed bundles at every API start and never deletes. Ten personas exist: four in organisation scope and
six in program scope. A role assignment binds a user or group to a persona in org scope or in one
program.
Summary
| Key | Name | Scope | Permissions | Bundle |
|---|---|---|---|---|
org_owner | Organisation owner | org | 13 | Full control of the organisation, including owner grants. |
org_admin | Organisation admin | org | 12 | Manages programs, users, groups and roles; cannot grant or revoke owners. |
org_member | Organisation member | org | 5 | Reads organisation settings, programs, users, groups and roles. |
org_auditor | Organisation auditor | org | 6 | Reads every organisation record including the audit log. |
program_owner | Program owner | program | 59 | Full control of one program across all four products, including owner grants. |
program_lead | Program lead | program | 58 | Runs the program across all four products; cannot grant or revoke program owners. |
scientist | Scientist | program | 41 | Investigates evidence, drafts plans, protocols, experiments and reports; approvals of protocols and reports stay with approvers. |
quality_reviewer | Quality reviewer | program | 31 | Compares records with SOPs, decides review findings and records deviations. |
manufacturing_specialist | Manufacturing specialist | program | 29 | Plans milestones, dependencies and open items for manufacturing planning; approvals stay with approvers. |
viewer | Viewer | program | 24 | Reads every program record; changes nothing. |
Matrix
One row per resource, one column per persona. Letters are the actions of the permission strings the
persona holds on that resource: r read, c create, u update, d delete, m manage, a approve,
l link, s sync, x use, w manage_owners. A dash means no permission on that resource.
| Resource | org_owner | org_admin | org_member | org_auditor | program_owner | program_lead | scientist | quality_reviewer | manufacturing_specialist | viewer |
|---|---|---|---|---|---|---|---|---|---|---|
org.settings | r u | r u | r | r | - | - | - | - | - | - |
org.programs | r c m | r c m | r | r | - | - | - | - | - | - |
org.users | r m | r m | r | r | - | - | - | - | - | - |
org.groups | r m | r m | r | r | - | - | - | - | - | - |
org.roles | r m w | r m | r | r | - | - | - | - | - | - |
org.audit | r | r | - | r | - | - | - | - | - | - |
program.settings | - | - | - | - | r u | r u | r | r | r | r |
program.members | - | - | - | - | r m | r m | r | r | r | r |
program.roles | - | - | - | - | r m w | r m | r | r | r | r |
program.connections | - | - | - | - | r m s | r m s | r | r | r | r |
program.audit | - | - | - | - | r | r | r | r | r | r |
program.agent_runs | - | - | - | - | r m | r m | r | r | r | r |
evidence.questions | - | - | - | - | r m | r m | r m | r | r | r |
evidence.sources | - | - | - | - | r m l | r m l | r m l | r | r | r |
evidence.findings | - | - | - | - | r m | r m | r m | r | r | r |
evidence.hypotheses | - | - | - | - | r m a | r m a | r m a | r | r | r |
evidence.gaps | - | - | - | - | r m | r m | r m | r | r | r |
evidence.agents | - | - | - | - | x | x | x | - | - | - |
plans.plans | - | - | - | - | r m a | r m a | r m a | r | r m | r |
plans.protocols | - | - | - | - | r m a | r m a | r m | r | r | r |
plans.experiments | - | - | - | - | r m | r m | r m | r | r | r |
plans.reports | - | - | - | - | r m a | r m a | r m | r | r | r |
plans.tools | - | - | - | - | r x | r x | r x | r | r | r |
plans.agents | - | - | - | - | x | x | x | - | - | - |
review.sops | - | - | - | - | r m a | r m a | r | r m a | r | r |
review.checks | - | - | - | - | r | r | r | r | r | r |
review.findings | - | - | - | - | r m a | r m a | r | r m a | r | r |
review.deviations | - | - | - | - | r m | r m | r | r m | r | r |
review.agents | - | - | - | - | x | x | x | x | - | - |
progress.milestones | - | - | - | - | r m | r m | r | r | r m | r |
progress.dependencies | - | - | - | - | r m | r m | r | r | r m | r |
progress.open_items | - | - | - | - | r m | r m | r m | r m | r m | r |
progress.approvals | - | - | - | - | r m a | r m a | r | r | r m | r |
How the bundles are built
org_owneris everyorg.*key;org_adminis the same minusorg.roles.manage_owners;org_memberis everyorg.*.readminusorg.audit.read;org_auditoris everyorg.*.read.program_owneris every program-scope key (program.*,evidence.*,plans.*,review.*,progress.*);program_leadis the same minusprogram.roles.manage_owners.scientistreads everything in program scope, holds all ofevidence.*, all ofplans.*exceptplans.protocols.approveandplans.reports.approve, plusprogress.open_items.manageandreview.agents.use.quality_reviewerreads everything, holds all ofreview.*andprogress.open_items.manage.manufacturing_specialistreads everything, holdsprogress.*exceptprogress.approvals.approve, plusplans.plans.manage.viewerreads everything in program scope and changes nothing.
Approvals stay with approvers by design: only program_owner and program_lead hold
progress.approvals.approve, plans.protocols.approve and plans.reports.approve together.
Source: api/app/auth/personas.py, api/app/auth/permissions.py, api/app/services/roles.py, PRODUCT-CONTRACT.md