brokerId / employerId before returning or mutating data.
Role Definitions
| Role (DB) | Session Role | Description |
|---|---|---|
SuperAdmin | admin | Full platform access. No broker or employer scope restriction. Reserved for platform operators. |
BrokerAdmin | broker | Full access within their brokerId. Manages schemes, members, compliance tasks for their clients. |
BrokerUser | broker | Same data scope as BrokerAdmin. UI may restrict specific administrative actions. |
Trustee | employer | Scoped to their employerId. Can view scheme data and submit required information. |
member role is defined in the type system for future member-portal use but is not currently active in the application UI.Tenant Scoping
Multi-tenancy is enforced structurally, not just by convention. Every database query that returns scheme, member, or employer data includes abrokerId or employerId filter derived from the authenticated session:
Role Mapping
The application maps database role names to session role values insrc/lib/auth.ts:
Session Claims
Every authenticated session carries:API Enforcement Pattern
Check role
If the route requires a specific role (e.g.,
broker or admin), check session.user.role. Return 403 Forbidden if insufficient.Audit Trail
All material actions — regardless of role — are written to the append-onlyaudit_logs table, recording the actorId, actorType, action performed, previous state, and new state. See Audit Logging for schema details.
AI Change Proposals
AI-generated suggestions never bypass RBAC. ThechangeProposals table enforces:
- Proposals are scoped to a
brokerId(and optionallyschemeId,memberId) - Only an authorised broker user can approve or reject a proposal
- Required attestations must be completed before approval is permitted
- Proposals auto-expire if not acted upon