Web: admin surface is role-gated, not matrix-gated #134
Labels
No labels
adr
android
area/calendar
area/design-system
area/i18n
area/jobs
area/offline
area/server
area/testing
bug
ci
duplicate
enhancement
help wanted
invalid
notifications
question
reliability
security
severity/low
severity/medium
tracking
web
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
eagraiclainne/app#134
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
From the RBAC matrix breakdown (2026-08-16), finding 1; also parity-report defect 11.
The entire web admin surface hangs off
isAdmin = roles.includes(Role.ADMIN)(auth.tsx:323) instead of matrix-derivedcan()affordances — the exact gap ADR-0028 closed everywhere else:Admin.tsx:56— the whole Admin page (the/adminroute itself is unguarded; the in-component check is the only client gate).MeMenu.tsx:112— the Admin nav link.Family.tsx:134,498,540— add member, and one flag gating four capabilities (AssignRoles, ClearPin, Update, Delete, end partnership).FamilyTree.tsx:328,618— link-a-relation affordances.Each control can gate on the verb it performs:
can("ApiKeyService","ListApiKeys"),can("UserService","Delete"), etc. Defensible today because the underlying rows are all ADMIN-only, but it is the recorded anti-pattern and breaks silently if a row ever widens.Working as designed (do not touch): the ADR-0020 PIN nudges and tour deck selection mirror server rules that are themselves role-based.