Platform · trust

Roles that survive a security review

A permission model is easy to demonstrate and hard to get right, and the difference shows up in two places: whether it is enforced below the application, and whether it applies to software as well as to people. Most systems fail one of those and nobody notices until a review.

DutyWho mayConflicts with
Create a vendorAP clerk · AP agentCannot also release payment
Code and post a billAP agent · AP clerkCannot also approve above threshold
Approve a billController · dept headCannot also create the vendor
Release a paymentCFO · controllerHuman only, at any amount
Prepare an accrualController agentCannot also post it
Post an adjusting entryControllerCannot also sign the close
Sign off the closeCFOHuman only, at any level
Change authority levelsAdministratorCannot also transact
Agents are subject to the same matrix as people. An agent holding two conflicting duties is the same control failure as a person holding them.
Enforced in the data layerSame model for agents and keysField-level, not just object-level

What it does

Six things, specifically.

Roles as templates

Controller, AP clerk, department head, auditor, portal user — as starting templates you adjust rather than build from nothing, with the differences from the template visible.

Scoped by structure

Tenant, entity, department, location, and project. A controller of two subsidiaries in a group of nine sees exactly two, enforced rather than filtered.

Financial verbs

Read, draft, post, approve, release, administer — not create-read-update-delete, because the difference between drafting a bill and releasing payment against it is four authorities rather than two verbs.

Thresholds per scope

Approve to $10,000 in one entity and $50,000 in another is a normal grant rather than a workaround, and it is what real approval matrices look like.

Field-level exposure

An invoice has a total, a cost, and a margin. A portal user sees the first and cannot request the others at any layer including exports.

Expiring grants

Access with an end date for auditors, contractors, and cover during leave. Permanent access granted for a temporary reason is how sprawl begins.

Enforced below the application

The common architecture checks permissions in the application layer: an endpoint asks whether this user may do this, and proceeds if so. It works until somebody writes an endpoint that forgets to ask, which is the single most common cause of data exposure in multi-tenant systems and a class of bug code review catches inconsistently.

Ours is enforced in the data access layer. Every query carries an actor and a scope, and a query without them is rejected rather than executed. A developer cannot write an unscoped read and have it succeed, because it fails below the code they are writing. Row-level security in Postgres sits underneath as defence in depth.

Ask any vendor whether a developer could write an unscoped query and have it run. “They wouldn’t” is a process control, not an architectural one.

One model for people, agents, keys, and portals

Most systems have a role model for users and something vaguer for automation and API access. That split is precisely how automated activity ends up outside the control framework — and with agents in the picture it becomes the difference between a defensible audit trail and one that describes something that did not happen.

An agent is an actor with its own identity and permission set. An API key is an actor. A portal user is an actor. All four are subject to the same conflict matrix, so a grant that would let one entity create vendors and release payments is rejected at creation regardless of whether it is a person or a key.

Why field-level matters more than expected

Object-level permissions answer whether you can see an invoice. They do not answer whether you can see its cost and margin, which sit on the same record. For customer portals, external auditors, and junior staff that distinction is the entire requirement.

A system that can only grant or deny whole objects forces a choice between over-exposure and maintaining a separate reporting copy — and the second is how most companies end up with a second uncontrolled database.

Limits

Where this does not help.

Not an identity provider

SSO via SAML or OIDC and SCIM provisioning on Enterprise. Your identity provider remains authoritative for who exists; we govern what they may do.

It cannot resolve an undecided structure

If nobody can say who approves what above $25,000, no permission model supplies the answer. That decision comes before configuration and is usually the slow part.

Break-glass exists

A small number of our engineers can reach production under time-bound, dual-approved, logged access reported to you. Pretending otherwise would be dishonest.

Questions

What people ask.

Do you support SSO and SCIM?
SAML and OIDC with SCIM provisioning on Enterprise, so joiners and leavers are handled by your identity provider rather than by somebody remembering.
Can permissions differ per entity?
Yes, and that is the normal case in a group. Different thresholds in different subsidiaries is a standard grant rather than a workaround.
How do agents fit the model?
As actors with their own identity and permission set, subject to the same conflict matrix as people. Credential inheritance would make every audit assertion unreliable.
Can we see who has what?
A permission report by actor, scope, object, and verb, exportable and dated. It appears on most controls questionnaires and should not need a support ticket.
Who at erp.io can see our data?
A small number of engineers under time-bound break-glass requiring a second approver, logged and reported to you. Routine support does not include production data access.

Send us your role structure.

We will map it into the model and flag the conflicts before anything is implemented.