Roles and Permissions¶
Applies to: All subscriptions
Purpose¶
State exactly what each role can do, so an administrator can map job functions to roles deliberately and answer access questions from documentation rather than by experiment.
Audience¶
System administrators, compliance and internal audit, implementation consultants.
Prerequisites¶
- User and Role Administration — particularly the three-gates model
Reference¶
The eight roles¶
| Role | Purpose | Transactional authority |
|---|---|---|
| Platform Super Admin | Platform administration across tenants | Full |
| Org Admin | Configuration and user administration within an organisation | None |
| Tax Controller | The checker: commits tax documents | Full for tax and logistics |
| Tax Executive | The maker: prepares tax documents | Prepare only |
| Approver | Approval Engine sign-off, without processing rights | None — invoice.approve and reads only |
| Transport Manager | Logistics operations | e-Way Bill family only |
| Logistics Operator | Logistics operations | e-Way Bill family only |
| External Auditor | Read-only assurance | None |
A system role is not an approval level
A user record carries two independent role fields. The system role above
decides which API calls the holder may make. sys_user.approval_role_key
decides which step of a multi-level approval they occupy — Finance Manager,
Finance Controller, CFO and so on.
Approving in production requires both, and a user with only one is not an error state: nothing is logged, nothing is refused, the person is simply never asked. This is the single most common approval misconfiguration. See Segregation of Duties.
Permissions held by every role¶
These informational reads within the user's own tenant are held by all eight roles:
dashboard.view · notifications.view · intelligence.view · upload.view · template.view · audit.view
They are kept deliberately separate from resource-specific permissions such as admin.view, so that widening one cannot silently widen another.
Role by role¶
Platform Super Admin¶
Identifier super_admin. Named Platform Super Admin everywhere a person meets it — the Users & Roles picker, the role chip in the top bar, the Permissions Matrix and the Help Centre — because it is Complifly's own platform role, not a senior administrator inside a customer organisation. There is no separate tier below it.
Platform-level administration, including across tenants. Holds the complete permission set: the full e-Invoice family, the full e-Way Bill and consolidated e-Way Bill families, reconciliation, master data, user administration, application reset and dataset deletion, template management including promotion, the full Invoice Generation family, numbering and ledger management.
Grant sparingly. This is the only role that reaches across tenant boundaries.
Org Admin¶
Configuration and administration without transactional authority. This separation is deliberate and is the design point of the role.
| Holds | Does not hold |
|---|---|
admin.view, admin.manage_users, admin.reset_app |
Any irn.* action |
admin.api — integration administration |
Any ewb.* or cewb.* action |
masters.view |
Master data editing |
numbering.manage — series definition is a configuration act |
Any invoice.* transactional action |
gl.manage, gl.view — chart of accounts, posting rules, calendar |
An org admin controls who has access and how the system is configured, but cannot themselves commit a transaction.
Tax Controller — the checker¶
Authority to finalise transactions.
| Area | Permissions |
|---|---|
| e-Invoice | irn.create, irn.generate, irn.cancel, irn.decrypt, irn.print, irn.view |
| e-Way Bill | The full family: create, generate, cancel, reject, extend, update Part-B, update transporter, multi-vehicle, change vehicle, distance, view |
| Consolidated e-Way Bill | cewb.generate, cewb.regenerate, cewb.view |
| Reconciliation | recon.view, recon.match |
| Masters | masters.view, masters.edit, masters.customer.edit, masters.item.edit |
| Templates | Upload, update, delete and promote |
| Invoice Generation | The full family, including invoice.approve, invoice.issue, invoice.cancel |
| Ledger | gl.view — reading the ledger and its reports. Configuring it is an administrative act |
Approve, issue and cancel live only here. That placement is what makes the segregation model work.
Tax Executive — the maker¶
Can prepare and correct, but cannot commit.
| Area | Permissions |
|---|---|
| e-Invoice | irn.create, irn.view, irn.decrypt, irn.print — not generate, not cancel |
| e-Way Bill | ewb.view, ewb.get_distance only |
| Reconciliation | recon.view, recon.match |
| Masters | masters.view only |
| Templates | Upload and update — not promote |
| Invoice Generation | invoice.view, invoice.create, invoice.edit, invoice.print — not approve, issue or cancel |
| Ledger | gl.view |
The absent permissions are the point of the role. A tax executive prepares work that a tax controller commits.
Approver — Approval Engine sign-off¶
Authority to clear an approval level, and nothing else. Added so that approval authority can be granted without transactional authority.
| Area | Permissions |
|---|---|
| Invoice Generation | invoice.approve — approve or reject a level on a document awaiting sign-off |
invoice.view, invoice.print — read the document and take a copy to review |
|
| e-Invoice | irn.view — the IRN state behind a cancellation request |
| Masters | masters.view — the customer and item the figures came from |
| Ledger | gl.view — including GET /v1/gl/approval/config, the matrix that explains why the document routed to them |
It holds no create, edit, issue, cancel, generate, promote or administrative permission. The complete set is nine permissions plus the six universal reads.
Why this role exists¶
invoice.approve was previously held only by Tax Controller and Super Admin. A business head, plant head, director or CFO who had to clear an approval level therefore had two options, and both were wrong:
- Make them a Tax Controller. That also grants
invoice.create,invoice.edit,invoice.issue,invoice.cancel,irn.generate,irn.cancel,ewb.cancel,masters.editandtemplate.promote. An approver who can raise and issue the documents they sign off is not a control. - Grant nothing and use Force Approve. Every senior sign-off is then recorded as
OVERRIDDENwith a bypass reason, which destroys the distinction between a real approval and an administrative override — the one thing the audit trail exists to preserve.
Assign Approver to people who sign off but do not process. Finance staff who do both keep Tax Controller, which still holds invoice.approve.
It is inert without an approval role¶
This role makes the Approve call reachable. It does not make a document arrive.
The workflow routes each level to the approval role that level requires and compares it against the caller's approval_role_key. A user with the Approver system role and no approval role assigned can open every document's workflow panel and act on none of them — with no error, because nothing has failed.
Assign both fields together. See Segregation of Duties for the approval-role ladder.
Transport Manager and Logistics Operator¶
Identical permission sets. Logistics only.
| Holds | Does not hold |
|---|---|
| The full e-Way Bill family | Any IRN generation or cancellation |
| The consolidated e-Way Bill family | Reconciliation matching |
irn.view — for cross-checking |
Master data editing |
masters.view |
Two role names exist for organisational clarity — a manager and an operator may be distinct positions — while the authority is the same.
External Auditor¶
Zero-touch access. View and print only, across every area including administration and the ledger.
irn.view · ewb.view · cewb.view · recon.view · masters.view · admin.view · invoice.view · invoice.print · gl.view
Note the overlap with Approver, which holds a similar read set. The difference is invoice.approve: an auditor observes the workflow, an approver acts in it.
Designed so that granting audit access is never a risk decision.
The complete permission matrix¶
The role descriptions above explain why the split is where it is. This table is the lookup underneath them: every permission the product grants, and which roles hold it.
Use it when you are handed a permission name. Hovering a greyed-out control in the product names the permission that would unlock it — for example ewb.update_partb. Search this table for that exact string, read across, and you have both the answer and the person to ask.
| Permission | Platform Super Admin | Org Admin | Tax Controller | Tax Executive | Transport Mgr | Logistics | Approver | Auditor |
|---|---|---|---|---|---|---|---|---|
| General | ||||||||
audit.view |
Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
dashboard.view |
Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
intelligence.view |
Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
notifications.view |
Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
upload.view |
Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
| e-Invoice | ||||||||
irn.cancel |
Yes | — | Yes | — | — | — | — | — |
irn.create |
Yes | — | Yes | Yes | — | — | — | — |
irn.decrypt |
Yes | — | Yes | Yes | — | — | — | — |
irn.generate |
Yes | — | Yes | — | — | — | — | — |
irn.print |
Yes | — | Yes | Yes | — | — | — | — |
irn.view |
Yes | — | Yes | Yes | Yes | Yes | Yes | Yes |
| e-Way Bill | ||||||||
ewb.cancel |
Yes | — | Yes | — | Yes | Yes | — | — |
ewb.change_vehicle |
Yes | — | Yes | — | Yes | Yes | — | — |
ewb.create |
Yes | — | Yes | — | Yes | Yes | — | — |
ewb.extend |
Yes | — | Yes | — | Yes | Yes | — | — |
ewb.generate |
Yes | — | Yes | — | Yes | Yes | — | — |
ewb.get_distance |
Yes | — | Yes | Yes | Yes | Yes | — | — |
ewb.multi_vehicle |
Yes | — | Yes | — | Yes | Yes | — | — |
ewb.reject |
Yes | — | Yes | — | Yes | Yes | — | — |
ewb.update_partb |
Yes | — | Yes | — | Yes | Yes | — | — |
ewb.update_transporter |
Yes | — | Yes | — | Yes | Yes | — | — |
ewb.view |
Yes | — | Yes | Yes | Yes | Yes | — | Yes |
| Consolidated e-Way Bill | ||||||||
cewb.generate |
Yes | — | Yes | — | Yes | Yes | — | — |
cewb.regenerate |
Yes | — | Yes | — | Yes | Yes | — | — |
cewb.view |
Yes | — | Yes | — | Yes | Yes | — | Yes |
| Invoice Generation | ||||||||
invoice.approve |
Yes | — | Yes | — | — | — | Yes | — |
invoice.cancel |
Yes | — | Yes | — | — | — | — | — |
invoice.create |
Yes | — | Yes | Yes | — | — | — | — |
invoice.edit |
Yes | — | Yes | Yes | — | — | — | — |
invoice.issue |
Yes | — | Yes | — | — | — | — | — |
invoice.print |
Yes | — | Yes | Yes | — | — | Yes | Yes |
invoice.view |
Yes | — | Yes | Yes | — | — | Yes | Yes |
numbering.manage |
Yes | Yes | — | — | — | — | — | — |
| Ledger | ||||||||
gl.manage |
Yes | Yes | — | — | — | — | — | — |
gl.view |
Yes | Yes | Yes | Yes | — | — | Yes | Yes |
| Reconciliation | ||||||||
recon.match |
Yes | — | Yes | Yes | — | — | — | — |
recon.view |
Yes | — | Yes | Yes | — | — | — | Yes |
| Master data | ||||||||
masters.customer.edit |
Yes | — | Yes | — | — | — | — | — |
masters.edit |
Yes | — | Yes | — | — | — | — | — |
masters.item.edit |
Yes | — | Yes | — | — | — | — | — |
masters.view |
Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
| Mapping templates | ||||||||
template.delete |
Yes | — | Yes | — | — | — | — | — |
template.promote |
Yes | — | Yes | — | — | — | — | — |
template.update |
Yes | — | Yes | Yes | — | — | — | — |
template.upload |
Yes | — | Yes | Yes | — | — | — | — |
template.view |
Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
| Administration | ||||||||
admin.api |
— | Yes | — | — | — | — | — | — |
admin.delete_datasets |
Yes | — | — | — | — | — | — | — |
admin.manage_users |
Yes | Yes | — | — | — | — | — | — |
admin.reset_app |
Yes | Yes | — | — | — | — | — | — |
admin.view |
Yes | Yes | — | — | — | — | — | Yes |
51 permissions across 8 roles. Generated from config/policies.js, the same module the API authorises against — do not edit this table by hand; run node tools/docs/gen-permission-matrix.js --write.
Mapping job functions to roles¶
| Job function | Role |
|---|---|
| IT administrator managing users and configuration | Org Admin |
| Indirect tax manager approving and committing documents | Tax Controller |
| Tax analyst preparing and correcting documents | Tax Executive |
| Dispatch supervisor | Transport Manager |
| Warehouse or dispatch clerk | Logistics Operator |
| Internal or statutory auditor | External Auditor |
| Complifly platform operations | Super Admin |
Map from what the person does, not from their job title. A "Finance Manager" may be a checker in one organisation and a preparer in another.
What is not configurable¶
Roles are fixed. There is no custom role builder and no per-user permission override. Access is shaped by three levers only:
- Which role a user holds
- Which registrations they may access
- Whether segregation of duties is enforced
This is a constraint worth stating early in an implementation, because customers frequently arrive expecting to define their own roles.
Validation¶
| Check | Method | Pass condition |
|---|---|---|
| Every user has a deliberate role | Review the user list with the process owner | Each mapping justified |
| Maker cannot commit | Sign in as a tax executive and attempt to generate an IRN | Refused or greyed out |
| Org admin cannot transact | Sign in as an org admin and attempt to generate an IRN | Refused |
| Auditor cannot change anything | Sign in as an auditor and attempt any action | All refused |
| Logistics cannot generate IRNs | Sign in as a logistics operator and attempt it | Refused |
| Template promotion restricted | Sign in as a tax executive and attempt to promote a template | Refused |
| Approval restricted | Sign in as a tax executive and attempt to approve an invoice | Refused, when segregation is enforced |
| Access review scheduled | Operations calendar | Recurring, with a named owner |
Perform these as real sign-in tests, not by reading the table. A permission that is documented but not enforced is a finding; a permission enforced but undocumented is a support cost.
Troubleshooting¶
| Symptom | Cause | Action |
|---|---|---|
| "Why can my colleague do this and I cannot" | Maker versus checker | By design when segregation is enforced. Explain the model rather than changing the role |
| A user needs one extra permission | No per-user overrides exist | Either move them to the role that holds it, accepting everything else it grants, or keep the current role. There is no middle option |
| An org admin cannot generate an IRN | By design — configuration authority excludes transactional authority | If they genuinely need it, they need a different role, and the control consequence must be accepted |
| A tax executive can suddenly approve | Segregation was relaxed | Check the setting. See Segregation of Duties |
| Screen present but everything greyed out | Role lacks the permissions | Fix the role, not the feature flag |
| Screen entirely absent | Feature flag, not role | See Feature Flags |
| Screens load with no data | GSTIN access | See GSTIN Access Control |
| Customer wants a custom role | Not supported | Map to the closest role and document the gap. Escalate as a product request if material |
| Too many super admins | Convenience during implementation | Reduce to the minimum. It is the only cross-tenant role |
Related Articles¶
- Segregation of Duties — how relaxation changes this table
- GSTIN Access Control — the third gate
- Feature Flags — the first gate
- User Lifecycle — assigning and changing roles
- Role Assignment — doing this during implementation