Skip to content

Finance permissions

This page used to hold a second copy of the finance permission grid. Two copies drift, and this one did: it showed CASHIER verifying payments, journal approval on approvals.approve, and CEO / GM / IT_ADMIN as super-admins. None of that is true.

The canonical grid is PERMISSIONS.md — §4 for the catalogue, §5 for role grants, §6.8 for the page-by-page finance actions. A drift test (src/test/permissions.matrix.test.ts) fails the build when code and that file disagree, and supabase/tests/access_model.sql fails when the database disagrees with either.

What to read instead

Question Where
Which permission gates this button? PERMISSIONS.md §6.8
What does this role hold? PERMISSIONS.md §5
Why is the split the way it is? ACC-011, ACC-012, ACC-021
Who may approve what, and why not their own work? Maker-checker
Which limits apply by amount? Numbering and approval limits

The three facts people most often get wrong

  1. SUPER_ADMIN is the only role with every permission. It holds them because every permission row is granted to it explicitly, by a trigger that also grants each newly created permission. There is no role-name bypass in the code. CEO and GM hold a leadership bundle; IT_ADMIN holds system settings only; ADMIN_HR holds no finance, approval, invoice or permission-editing rights.
  2. CASHIER records receipts and nothing else — finance.view and finance.payments.record. finance.payments.verify was removed from the bundle (ACC-021).
  3. Break-glass and destructive rights are super-admin only — finance.journals.approve_own, finance.journals.reverse_own, finance.ledger.rebuild, finance.ledger.reset, finance.years.close, finance.periods.close, accounts.delete, and the role and permission editing rights.