ADR-0121: The Project Administrator Role — Per-Scope Administration With Read Access, Seeded in the Base Catalog¶
- Status: accepted (2026-08-22 — his request: "a 'project' admin role in the base catalog, that automatically assigns all 'admin' functions on a project. In this case, I'd even argue that data access for these roles might be activated"; the recommended permission cut agreed verbatim)
- Date: 2026-08-22
- Deciders: Nicolas Burri
- Relates to: ADR-0012 / REQ-ADM-004 (admin ≠ content — the boundary this DEVIATES from at project level, deliberately and narrowly), ADR-0107 (assignment-reach audit anchoring — the machinery the GLOBAL boundary's friction required, V080's note being the evidence), ADR-0114 rule 1b (name-beats-function at import — consequence stated below), ADR-0117 (role documentation), V071/V073/V078 (the atomic-commit convention for the permission vocabulary this extends).
Context¶
The base catalog seeds content roles and ONE admin role — the GLOBAL System Administrator. There is no way to hand a colleague "administer this project, and see what it shows you" without either granting system administration (installation-wide, cross-tenant) or hand-building a role per installation. Nicolas hit exactly this when inviting colleagues: he wanted project-admin access for evaluation, and the catalog had nothing to offer.
Why data access is included, and why that is principled rather than a compromise. Admin ≠ content is absolute at GLOBAL because it is a CROSS-TENANT boundary: the installation operator must not read customers' QMS. At project level no such boundary exists — the role is defined in the catalog but a project must still activate and staff it, so content access is granted by the project's own deliberate act inside its own trust domain. The GLOBAL boundary's strictness also has a recorded cost: V080 documents that the System Administrator could not drive surfaces it was granted, because audit appends were VIEW-gated and the role held no VIEW — it took ADR-0107 to fix. A project administrator WITH read access avoids that friction class entirely.
Decision¶
-
A seeded base-catalog role
Project Administrator, ensured at bootstrap on every startup (theSYSTEM_ADMIN_PERMISSIONSpattern — existing installations gain it on upgrade, free). -
The permission cut (his agreement, verbatim list):
- In — administer, staff, observe:
ASSIGN_ROLES,MANAGE_USERS,ACTIVATE_CATALOG_ENTRIES,CONFIGURE_REVIEW_POLICY,MANAGE_TRAINING, plus the read-class content permissionsVIEWandVIEW_TRACEABILITY. -
Out — deliberately: every authoring/approval permission (a project administrator approving documents would poison four-eyes hygiene), and the records-governance cluster
DISPOSE_RECORDS,APPLY_LEGAL_HOLD,MANAGE_RETENTION,ERASE_PERSONAL_DATA— that is a records-officer function, not administration, and bundling would dilute both roles. -
"Automatically all admin functions" means maintained-by-guard, not wildcard. An explicit
PROJECT_ADMIN_PERMISSIONSlist plus a classification guard test: every permission in the vocabulary must be classified — global-admin, project-admin, content, records-governance, or retired — so a new permission fails the build until someone decides where it belongs. The inventory is the documentation (theRlsPolicyInventoryTestshape). -
ADR-0012 is amended in scope, not repealed: admin ≠ content remains absolute at GLOBAL. This role is the recorded, narrow exception at project level, with the activation-and-staffing act as its gate.
Consequences¶
- ADR-0114 rule 1b: a future import carrying a role literally named "Project Administrator" will adopt onto the seeded one — name beats function. Stated here so it is a decision, not a surprise; judged desirable (the imported org's project admins land on the role that means exactly that here).
- Realization rides the v0.9.16 wave: bootstrap ensure + the classification guard test + nothing new in the webui (activation and staffing surfaces already exist).
- ADR-0117 applies: the role wants a
described_bydocumentation link like every other; the seeded description states the read-access rationale so a project activating it knows what it grants.