Skip to content

Roles & permissions

There are seven roles. Two are for client contacts, five are for staff users. Permissions are encoded in code — see packages/auth/src/rbac.ts — and the RBAC matrix page is generated from that file at build time, so it cannot drift.

Client-contact roles

These are the magic-link recipients. They never see the staff dashboard.

  • Client submitter — usually the client's HR or finance person. Submits the monthly intake (payroll), responds to unreconciled items (bookkeeping). Cannot approve.
  • Client approver — usually a director / FC. Approves the cycle (payroll). Cannot submit.

Staff roles

RolePrimary surfaceCan do
Payroll ExecutivePayroll cyclesManage cycles, resolve issues, generate exports, upload outputs, request approvals
Payroll LeadPayroll cycles + adminEverything Payroll Executive does, plus override blocking issues, manage clients, manage templates
BookkeeperBookkeeping batches & reconciliationManage batches, approve journal entries, generate upload files, run reconciliation
Senior AccountantBookkeeping + adminEverything Bookkeeper does, plus override journal flags, manage clients, manage templates
Platform AdminBoth products + staffManage staff users, manage clients, manage templates, view all cycles and batches; can override issues across both products

How escalation works

  • A blocking validation issue on a payroll submission can be overridden by a Payroll Lead or Platform Admin via the POL approval flow. A Payroll Executive cannot override on their own.
  • A flagged journal entry (low confidence, foreign-currency, keyword-only match) can be overridden by a Senior Accountant or Platform Admin. A Bookkeeper can approve normal entries but not override flags.
  • Anything tenant-bleed-suspected escalates to Platform Admin and follows the runbook.

Where this is enforced

Three layers, all reading the same matrix:

  1. API — every Fastify route guards with requirePermission(Action.X).
  2. Web sidebarapps/web/src/lib/dashboard-nav.ts mirrors the matrix; nav entries the role can't access don't appear.
  3. Worker jobs — staff-triggered jobs check the actor's role before running.

If you find a discrepancy — e.g. the sidebar shows a link your role can't access — that's a bug, not your error. Open an issue.

Internal use only — BreezyCorp