Every workspace starts with one role that can do all 258 things.
The account you sign up with is attached to an Admin role holding every permission in the product, because a workspace nobody can administer is worse than one that is over-permissioned on its first afternoon. Governance here is the work of carving that down — and the product is built so that the carving cannot strand a user, orphan a route, or lock the last administrator out of their own workspace.
258Named permissions, grouped into the 24 modules they belong to.
2Independent gates on a protected route. They fail differently and say so.
420Routes whose permission is declared in a map a test compares to reality.
3Lock classes that refuse edits which would leave nobody in charge.
Where governance actually starts
A workspace nobody can administer is a worse failure than one that is over-permissioned.
We learned that from the provisioner. An earlier version created the tenant, the user, the default warehouse and the reference data in a single transaction, with the demo items seeded last — so anything that threw in the tail rolled the Admin role back with it. The workspace came up, the customer could sign in, and every administrative screen answered “System misconfiguration: No Admin role.” Signup now commits the tenant and the user first, and the grants run as their own stage that logs rather than throws.
One role, every permission
The provisioner creates a role named Admin for the new tenant, grants it each of the 258 permissions in the catalogue, and attaches the signup user to it. Nothing else is created. There is no “Standard” and no “Approver” waiting for you — a starter role built on a guess about your org chart is a role somebody has to audit before they can trust it.
You build the second role
The role editor lists all 258 permissions under the 24 module headings below, with the whole group selectable at once. Most workspaces get to a workable model with three or four roles: someone who raises requests, someone who approves them, someone who touches money, and the person who set it all up.
Roles never leave the tenant
A role is created against your tenant and resolved against your tenant. Permission lookups go through the user's roles for that tenant, so a person who belongs to two workspaces carries two independent permission sets and never the union of them.
Two gates, in order
“You can't do that” is two different sentences, and the product refuses to blur them.
A protected route runs the plan check first and the role check second. They are independent, they return different status codes, and they end in different places — because a person who has been told to do a job and cannot is owed an accurate reason. Blur the two and every plan limit arrives at your administrator's desk as a support ticket about broken permissions.
402 · plan_restricted
Your workspace does not carry this capability
“This feature is not available on your current plan.”
Nothing to do with the person. The plan the workspace is on does not include the capability, so no role in the workspace can hold it — not even the Admin that holds all 258. On the web the user is returned to the page they came from with the upgrade prompt raised; over the API it is an HTTP 402 carrying plan_restricted: true and the permission name, so an integration can tell the two refusals apart without scraping a message.
One deliberate exception: delete_roles skips the plan gate entirely. A workspace that moves down a plan must still be able to tidy up the roles it built on the way up, and asking somebody to upgrade in order to delete something is a trap.
403 · permission_denied
Your role does not carry this permission
“You do not have the required permission to perform this action.”
The capability exists in the workspace and somebody has it — just not this person. The web response is a dedicated refusal page rather than a generic 403, and it names the permission that was missing, so the message your administrator receives is “I need approve_purchase_orders” rather than “it says I'm not allowed.” A user carrying no role at all is refused at the same gate with its own wording.
Over the API the same refusal is an HTTP 403 with code: permission.denied and the permission name in the body.
The order matters and is not arbitrary. Plan first means a downgraded workspace gives the same answer to every user rather than a confusing mix of upgrade prompts and access denials that depends on who happens to be logged in.
The catalogue
258 permissions, grouped the way the product is, not the way a security questionnaire is.
This table is generated from the same configuration the role editor reads, so it is the real catalogue rather than a marketing summary of it. Granularity follows risk: Inventory and Human Resources carry the most because they hold the most ways to move something irreversibly, while Dashboard carries one, because there is one thing to decide about it.
Dashboard1
Inventory34
Item Categories5
Asset Tracking21
Procurement25
Vendors5
Human Resources29
Projects15
Helpdesk6
Sales19
Accounting17
Automation8
Reports & History10
Custom Fields4
Users & Roles9
Reasons5
Security10
Document Vault2
Integrations6
AI & Insights6
Tax & Compliance3
Notifications & Settings9
Logs & Trash6
Help & Support3
General0
Permission names are the same strings in the role editor, in the route definitions, in the API refusal bodies and in the audit trail. There is no display layer translating approve_purchase_orders into something friendlier and losing the mapping on the way, which is what makes an access review possible to finish.
Removing a role
You cannot delete a role out from under the people holding it.
The obvious way to build role deletion is to delete the role. The users attached to it then hold no role, every permission check fails, and eleven people discover this at once on a Monday. The delete here is a four-step sequence and the destructive step is last.
01
The lock is checked before anything else
If the role is one of the system defaults, the delete is refused outright with “System default roles cannot be deleted” and nothing further runs.
02
The interface probes before it asks you to confirm
Before showing a confirmation, the screen asks the server what deleting this role would cost. If anyone holds it, the answer is a 422 carrying the number of affected users and the list of roles they could be moved to — so the dialog you see says “7 users” and offers destinations, rather than asking “are you sure?” about a number you do not know.
03
A destination is required, and protected roles are not offered as one
The delete is refused until you nominate a role to move those users into. The candidate list excludes the role being deleted and excludes protected roles, so “tidy up by sweeping everyone into Admin” is not one of the offered exits.
04
Reassign, then delete, then write it down
Every holder is moved to the nominated role first. Only then is the role removed, and the removal is recorded against your workspace with the role name and who did it.
Three lock classes
The role model is allowed to refuse you, and the case it refuses is the one that ends in a locked-out workspace.
Every one of these is a rule about a mistake that is easy to make in a role editor at four in the afternoon and expensive to undo. They are configuration rather than hard-coded, so a deployment can extend the list, but the shipped defaults are these.
name-locked & delete-locked
Admin and User cannot be renamed or removed
These two are the workspace's anchors. Renaming Admin to something local — and the temptation is real — breaks the identity the provisioner and the impersonation path both look for by name.
Try to delete either and the role list refuses, before the user-count probe runs.
permissions-locked
Admin's permission set cannot be edited
Not by another administrator, and not by itself. This is the lock that prevents the single most common self-inflicted lockout in a role system: an administrator tidying up their own role, unticking manage_roles, saving, and losing the ability to put it back.
Admin holds all 258 permissions permanently. Narrow access by moving people off it, not by narrowing it.
forbidden name
A role called “Super Admin” cannot be created
That name means something specific on the platform side, and a tenant-level role wearing it would read in a log line, an audit export or a support conversation as something it is not. The name is reserved and creation is refused, whatever the casing.
Refused on create and on rename, matched case-insensitively and trimmed.
How the gates stay on
A route that quietly loses its permission looks exactly like a route that never had one.
This is the failure mode a role system actually dies of. Nobody removes a gate on purpose; a route gets copied, a middleware line does not come with it, and the application behaves identically for every honest user for as long as it takes somebody to notice. So the permission each route requires is declared in a map, and a test compares that map against the middleware the router really has.
340 web routes and 80 API routes are declared
The map has two halves because the two surfaces are gated separately, and an entry has to exist in the half it belongs to. The test fails in both directions — a route whose live middleware does not match its declaration, and a declaration pointing at a route that is no longer there. The second half matters more than it sounds: a stale entry is how a map stops describing the system while still passing.
Routes that serve a stored file get their own permission
The controller behind proof-of-payment files, vendor invoices and quotation attachments checks the tenant and deliberately nothing else — so the permission has to come from the route. Nine of those routes were tenant-only until August 2026, which meant any signed-in member of a workspace could pull them whatever their role. The signature routes beside them had gates; the attachment routes did not, and the module read as covered. They are gated and mapped now, and the test is what keeps them that way.
Both halves run in CI and fail the build. That is the honest version of “auditable access control”: not a claim that we are careful, but a check that runs whether or not we are.
The role audit
Three events, kept separately from the notification a person clicks away.
There is a role audit screen in the workspace, paginated and scoped to your tenant. It is worth being exact about what lands in it, because “full audit trail” is the sort of phrase that survives a procurement questionnaire and then disappoints somebody in a review meeting.
A role was created
The role name and the person who created it, timestamped.
A role's permissions were updated
The role name, the person, and the number of permissions the role holds afterwards.
A role was deleted
The role name and the person, written after the holders have been reassigned.
What that is not
The permissions entry records a count, not a diff. It will tell you that Grace changed the Warehouse Supervisor role and that it now holds 31 permissions; it will not tell you that the one she added was delete_adjustments. For a periodic access review that is usually enough to find the change worth asking about. For an evidence pack that has to show what changed, it is not, and a per-permission before-and-after is in the ledger below as something we can add.
Separately, the audit trail across the rest of the product is hash-sealed and verifiable, with no delete button anywhere in the interface. That is a different mechanism with a stronger guarantee, and it has its own page.
Before you quote this in a tender
The access-control rows in a security questionnaire, answered without the adjectives.
Governance & roles — what is in the product today
What AWRA OpsHub does today
Role-based access control with 258 named permissions across 24 modules, all editable per role.
Two independent gates on protected routes — plan first (402), role second (403), each with its own wording and its own machine-readable code.
A declared permission per route, 340 web and 80 API, compared against live middleware by a test that fails the build in both directions.
Role deletion that reassigns before it deletes, with a user count and a destination list shown before you confirm.
Locks on the roles that would strand a workspace — Admin and User cannot be renamed or deleted, Admin's permissions cannot be edited, and the Super Admin name is reserved.
Per-tenant role resolution, so one person in two workspaces carries two separate permission sets.
A role audit screen recording creation, permission updates and deletion with actor and timestamp.
Multi-factor authentication, device trust and session controls as separate, individually permissioned capabilities.
More we can add to your workspace
A per-permission diff in the role audit — today the update entry carries a count, so an evidence pack showing exactly which permission moved is work we would do for you.
SCIM provisioning, so joiners and leavers in your identity provider create and deactivate workspace users without an administrator doing it by hand.
Identity-provider group to role mapping, letting an AD or Google group decide the role at sign-in rather than an administrator assigning it after.
A request-and-approve workflow for access itself, where a user asks for a permission and a named approver grants it on the record.
Time-boxed role assignments that expire on their own — today a temporary elevation is granted and removed by a person, and the removal is the step that gets forgotten.
A scheduled access-review campaign that asks each manager to confirm their people's permissions on a cadence and records the sign-off.
Segregation-of-duties rules that refuse a role combining two permissions you have declared incompatible.
Where we point you to a specialist
We will not tell you what your access model should be. Which of your staff may approve a purchase order is a question about your controls and your insurance, and a vendor who answers it in a sales meeting is selling you a liability.
We point you to your auditor on whether this satisfies a specific control framework. We can show you exactly what the system does and what it records; whether that clears ISO 27001 A.9 or your lender's conditions is their determination to make, not ours.
A plan-level capability grant sits with us rather than in your workspace. Where a plan does not carry something you need, we can grant it against your tenant with a reason and an expiry on the record — but that is arranged with us, so it stays a conversation rather than a switch.
Anything in the middle column is a scoped piece of work on a system that already has the permission catalogue, the route map and the audit surface to hang it on. Tell us which row matters and we will come back with what it takes.
Adjacent
Roles decide who may act. These decide what happens when they do.
Run inventory, procurement, assets, sales, and field work with approved AWRA guidance for setup, migration, integrations, security, pricing, and support.
We use necessary cookies for secure sessions. With your permission, we also use cookies and browser storage for preferences, analytics, and demo engagement. Privacy Policy
AWRA OpsHub
Cookie settings
Cookie Consent Manager
Necessary cookies stay on for login, CSRF protection, and security. You can choose the optional categories below.
Overview
General Information
AWRA uses cookies and browser storage to keep public pages secure, remember selected preferences, measure website performance, and manage demo engagement prompts.
You can choose whether functional and marketing engagement storage apply. Analytics measurement is always active in this AWRA setup.
These settings apply to AWRA public website experiences such as the homepage, feature pages, pricing calculator, blog, help center, and request-demo page. Authenticated dashboard and vendor portal sessions still rely on required security cookies.
Required
Always active
Functional
Optional
Analytics
Always active
Marketing
Optional
For more context on privacy handling, open the Privacy Policy.
Required Cookies
Required Cookies
Always Active
Required cookies and storage support basic website delivery, secure sessions, request protection, and remembering the consent choice itself.
These cannot be switched off from this manager because disabling them would break login/session behavior, form protection, or the ability to remember the privacy choice you save.
Cookie details
Session security: keeps secure server sessions working while browsing AWRA.
CSRF protection: helps verify form submissions and protect requests.
Consent record: stores the preference decision so the banner does not keep asking after a choice is saved.
Examples: Laravel session cookies, CSRF tokens, and the AWRA consent preference record.
Duration: session security can expire with the browser/session; saved consent can last longer so the same browser remembers the choice.
Functional Cookies
Functional Cookies
Functional storage improves the public website experience by remembering interface choices, helper states, dismissed notices, and short-lived interaction preferences.
Turning this off does not stop secure required cookies or analytics. It only limits optional convenience memory.
If disabled, AWRA may show some helper prompts again or forget non-essential display choices. Core public pages, contact forms, and request-demo forms still work.
Cookie details
UI preferences: remembered display choices and helper states where available.
Dismissed notices: session-level or preference-level memory for notices the visitor has closed.
Frequency helpers: optional browser storage that prevents repeated prompts when allowed.
Examples: localStorage or sessionStorage values for dismissed banners, guide/helper states, and lightweight public-page preferences.
Effect when off: AWRA avoids optional convenience memory unless it is also allowed through marketing and engagement preferences.
Analytics Cookies
Analytics Cookies
Always Active
Analytics helps AWRA understand public page performance, traffic patterns, and content usefulness so we can improve the marketing website.
This category does not by itself enable demo popups, exit-intent prompts, or advertising pixels. Those are controlled by Marketing & engagement.
In this AWRA setup, Google Analytics and Google Tag Manager measurement are treated as mandatory website measurement and remain active.
Cookie details
Google Analytics / GTM: measures aggregate traffic and page activity.
Performance insight: helps identify which public pages, docs, and demo paths visitors use.
Operational signal: supports website quality decisions without enabling demo popups by itself.
Examples: Google measurement identifiers such as GA/GTM tags and related browser identifiers set by Google scripts.
Use: page views, source/referrer trends, public content performance, and product education page effectiveness.
Marketing & engagement
Marketing & engagement
Marketing and engagement storage supports demo prompts, exit-intent prompts, campaign attribution, and future advertising pixels.
When disabled, AWRA will not auto-open demo or exit-intent popups. CTA buttons can still open a form because that is a direct visitor action.
When enabled, AWRA can remember that a visitor already saw, dismissed, or submitted a demo prompt so the same popup is not repeated aggressively.
Cookie details
Demo prompt memory: tracks whether an auto prompt or exit prompt was recently dismissed.
Demo submission memory: avoids asking again after a visitor submits a demo request.
Campaign context: keeps source page, referrer, and UTM context available for demo requests.
Examples: popup frequency caps, demo-submitted flags, engagement source fields, and UTM/referrer context.
Effect when off: auto demo prompts and exit-intent prompts stay blocked; normal navigation and manually clicked CTA buttons still work.