On this page
The two-layer permission model
CashSheet uses two separate permission layers. Both have to allow an action for it to go through.
Layer 1 · Entity access
A per-user, per-entity flag. Values: read, write, or suspended. Controls whether the user can see any data from a given entity at all.
Stored on the EntityManagementModel row that links a user to an entity.
Layer 2 · Feature gates
Django auth_permission rows that gate specific features — can view invoices, can manage sales orders, can run LP solve, etc. Controls what the user can do within entities they already have access to.
Granted via Django groups (which is what the canonical groups below are).
In practice: both layers must say yes. An accountant who has write access to your entity but isn't in the AccountingManager group can't edit an invoice. A user in AccountingAdmin but with suspended entity access can't see anything.
The canonical groups
CashSheet ships with three role tiers — Viewer, Manager, Admin — for each functional area. They're seeded by the seed_ops_console_groups management command and editable from the Ops Console.
Accounting (financial_accounting module)
AccountingViewer
Read-only access to the entire accounting module: dashboard, chart of accounts, ledger, invoices, bills, customers, vendors, bank accounts, payments, journal entries, sales orders, receipts, financial statements, items, sales tax.
AccountingManager
Everything Viewer can do, plus manage all the operational accounting records: create and edit invoices, bills, customers, vendors, purchase orders, bank accounts, payments, journal entries, sales orders, receipts, items, and sales tax.
AccountingAdmin
Everything Manager can do, plus structural admin: manage entities themselves, manage units, run closing entries, import accounting data. Reserved for controllers and CFOs.
Production Planning (production_planning module / CutSheet)
PlanningViewer
Read-only access to the floor view, production schedule, shift assignments, and LP results. Good baseline for sales reps who need to see availability without changing the plan.
PlanningManager
Everything Viewer can do, plus edit the production schedule, manage shift assignments, and trigger LP solver runs on demand.
PlanningAdmin
Everything Manager can do, plus approve production plans. Reserved for plant managers and operations directors.
Assigning users to groups
From inside your silo:
- Sign in as a user who has Ops Console admin access.
- Open Ops Console → Roles.
- Click the group you want to assign (e.g. AccountingManager).
- In the user list, click Add user and pick the user from the search box.
- Save. Effects are immediate — the user's next page load will reflect the new permissions.
You can also see all groups a user belongs to on the user detail page (Ops Console → Users → click user). Users in multiple groups get the union of permissions across all of them.
Creating custom groups
If the canonical Viewer/Manager/Admin tiers don't fit your org chart, you can create custom groups in the Ops Console:
- Ops Console → Roles → Create group.
- Give it a descriptive name (e.g.
SalesRepReadonly,ShiftSupervisor). - Check the specific permissions you want this group to have. Only permissions in the curated registry appear as checkboxes — Django internals and auto-CRUD permissions are filtered out, so you can't accidentally grant access to platform-level admin or third-party app internals.
- Save. The new group is immediately available for assignment.
Note: non-superuser admins can only grant permissions they themselves hold. So if you're not an AccountingAdmin, you can't create a group with manage_entities in it. This is enforced by the platform — see grantable_permissions_for in ops_console.services.authz.
Audit trail
Every group assignment, permission grant, and group change is captured in the audit log. The Ops Console has a dedicated Audit Log view with search and filter UI — you can answer questions like:
- Who added person X to group Y, and when?
- What permissions did group Z have on a specific date?
- Show every action user W took in the last 7 days.
This is the answer to a USDA auditor's “who could have done this?” question. The data is on disk and queryable from day one — you don't need to set up logging separately.
Best practices
- Start everyone as Viewer. Escalate to Manager or Admin only when a specific need arises. It's easier to add permissions than to take them away.
- One AccountingAdmin per tenant + one backup. Two people who can do structural admin (closing entries, entity management) is the right count for most orgs — fewer is a bus-factor risk; more is access creep.
- Review group membership quarterly. People change roles, leave, change scope. Quarterly walk-through catches stale access before it's a problem.
- Don't share accounts. Every person who needs access should have their own platform account and silo membership. The audit log only helps if it ties actions to specific people.
- Use custom groups for cross-functional roles. If your shift supervisor needs to do both AccountingViewer things AND PlanningManager things, give them both groups — don't create a frankenstein single group with mixed permissions.