Roadmap item 4 — Authentication & role-based access control
Reference: ROADMAP.md item 4; AGENTS.md §1.5 (multi-role, multi-site access model) and §3.3 (audit trail is meaningless without identity).
Gap
No login, no session, no enforcement. Anyone can cast committee votes as anyone, edit protocols, or change admin lookup data. This is the biggest trust gap before the app could be used for anything real — and it's the missing piece that keeps the audit log (item 11) from recording who acted.
Implemented so far (graduated access — Aug 2026, PR #74)
- Server gate (
server/src/access.js): anonymous users can read everything and author ordinary protocol content; governance writes need a known persona — committee review (votes/comments/assignments) needs a committee-eligible or office role, admin CRUD / review assignments / transfer & amendment decisions need an office role. Deliberately not auth — a self-declared X-Actor name still passes.
- Client identity (
client/src/identity.ts, ActorPicker — item 17): an optional persona picker in the header attaches X-Actor to every request; the audit log attributes actions to the picked persona. audit_log.actor_key is reserved for a verified identity once real auth lands (no migration needed).
- Access banners (
client/src/components/AccessBanner.tsx): amber courtesy banner on the Admin/Committee pages when the acting persona (or lack of one) isn't who those pages are for — a signal, not enforcement.
Remaining work (why this stays open)
- Real auth (session/JWT or institution SSO) with roles mapped to the existing
personnel table: PI, Researcher Staff, IACUC Committee Member, IBC Member, Admin.
- Role/site switching UI (per Loyola's Site / Role / PI Group model in AGENTS.md §1.5).
- Populate
audit_log.actor_key with the authenticated user on every route.
Tests
Server: route auth guards + role checks (401/403 paths) — covered by the graduated-access suite. Client: nav gating + hidden actions by role (not yet). e2e: login flow + forbidden-action path (not yet). Audit: entries carry actor_key (not yet).
Roadmap item 4 — Authentication & role-based access control
Reference:
ROADMAP.mditem 4; AGENTS.md §1.5 (multi-role, multi-site access model) and §3.3 (audit trail is meaningless without identity).Gap
No login, no session, no enforcement. Anyone can cast committee votes as anyone, edit protocols, or change admin lookup data. This is the biggest trust gap before the app could be used for anything real — and it's the missing piece that keeps the audit log (item 11) from recording who acted.
Implemented so far (graduated access — Aug 2026, PR #74)
server/src/access.js): anonymous users can read everything and author ordinary protocol content; governance writes need a known persona — committee review (votes/comments/assignments) needs a committee-eligible or office role, admin CRUD / review assignments / transfer & amendment decisions need an office role. Deliberately not auth — a self-declaredX-Actorname still passes.client/src/identity.ts,ActorPicker— item 17): an optional persona picker in the header attachesX-Actorto every request; the audit log attributes actions to the picked persona.audit_log.actor_keyis reserved for a verified identity once real auth lands (no migration needed).client/src/components/AccessBanner.tsx): amber courtesy banner on the Admin/Committee pages when the acting persona (or lack of one) isn't who those pages are for — a signal, not enforcement.Remaining work (why this stays open)
personneltable: PI, Researcher Staff, IACUC Committee Member, IBC Member, Admin.audit_log.actor_keywith the authenticated user on every route.Tests
Server: route auth guards + role checks (401/403 paths) — covered by the graduated-access suite. Client: nav gating + hidden actions by role (not yet). e2e: login flow + forbidden-action path (not yet). Audit: entries carry
actor_key(not yet).