User guide

Roles and Permissions

Looking for what it does rather than how to use it? Read the Roles and Permissions overview .

Last verified against the codebase: 2026-07-27. Where a capability exists but is not enforced, this guide says so rather than implying it is.


What it is

Every request into Solidlio is decided by three things: which portal the caller is in, what organization role they hold, and which tenant the data belongs to.

On top of that, each organization keeps a directory of named roles — Technician, Dispatcher, Accountant, and any you create — which decide who gets routed work, who is asked to approve spend, and who gets notified.


The three role vocabularies

Solidlio has three separate sets of role names. They are not interchangeable, and knowing which one you are looking at removes most of the confusion in this area.

VocabularyWhere it livesWhat it decidesValues
Organization roleOrganizationMembership.role, one per person per organizationAuthorization. Every API route’s floor is expressed in this vocabularyplatform administrator › MSP administrator › MSP technician › organization administrator › power user › CUSTOMER
Job-function roleRole + PersonRole, many per personRouting and reporting — approver groups, notification targets, staff roster filters13 shipped system roles plus any custom role you create
Account roleAccountMember.role, one per person per accountWho administers the billing account — invites, member removal, account settingsOWNERADMINMEMBER

Platform staff carry a fourth, narrower set — see section 12.

The single most useful thing to remember: the organization role is the one that grants or refuses access. A person with the job-function role “Administrator” and the organization role CUSTOMER is a customer.

The organization-role hierarchy is ordered, and the order surprises people

platform administrator > MSP administrator > MSP technician > organization administrator > power user > CUSTOMER

MSP technician outranks organization administrator. That is correct — a technician at the managed service provider is operating above the client’s own administrator — but it means “administrators only” cannot be written as “organization administrator and above”, because that phrase includes every technician. Solidlio therefore has two guard shapes:

GuardShapeReads asAdmits
requireMinRole("X")Rank“X and everyone above X”Everything at or above X in the list
requireAnyRole(a, b, c)Set“exactly these roles”Only the named roles, in any order

Role administration uses the set (platform administrator, MSP administrator, organization administrator). Everything else in this area uses the rank.


How an authorization decision is made

Four checks run, in this order. All four must pass.

  1. A downstream service never re-reads the token.
  2. Portal. requirePortal(...) refuses a caller whose active portal is not one of the named ones. Which portals a person may activate is derived from their roles, not chosen freely — see section 5.
  3. Role floor. requireMinRole (rank) or requireAnyRole (set) on the route. There are 662 role-floor call sites across the services: 531 at organization administrator, 58 at MSP administrator, 39 at MSP technician, 24 at platform administrator, and one each at power user and CUSTOMER.
  4. Tenant scope. accountScope(req) is spread into the database query so the row set is confined to the caller’s account. Platform admins are unscoped; customer-portal callers are pinned to their single organization; everyone else sees any organization inside their account. A caller with no trusted account context matches nothing.

Steps 3 and 4 answer different questions and neither substitutes for the other. The role floor answers what rank is the caller; the tenant scope answers whose data is this. A route with only a tenant check will happily let a customer edit their own organization’s administrators.


Permission matrix

Capabilityplatform administratorMSP administratorMSP technicianorganization administratorpower userCUSTOMER
Access the platform portal
Access the MSP portal
Access the organization portal
Access the customer portal
List people in the tenant
Read own effective permissions
Read someone else’s effective permissions
Create a person
Edit or deactivate a person
List roles
See who holds a role
Read the permission catalogue
Create a custom role
Edit / delete an organization’s own role
Clone a role into an organization
Change a role’s permission set
Assign or remove a job-function role
Change someone’s organization role (access level)
Edit or delete a platform-wide (global) role
Grant a platform-administration permission
Create, edit or delete a permission in the catalogue
Assign a membership role above your own tier

Notes on specific cells:

  • MSP technician can read roles but not write them. The read floor is a rank (a technician servicing a client needs to see who is who); the write floor is a set that names the three administrator roles. This matches what the web portals show — the MSP role screen offers create/edit/clone/delete only to MSP administrator, the org role screen only to organization administrator.
  • “List people in the tenant” is open to every authenticated role because the people-picker on a ticket needs it. The result is still bounded by accountScope, and a customer-portal caller sees only their own organization.
  • The last row applies to everyone including platform admins: a caller may assign a membership role at or below their own tier and no higher. An unknown or missing caller role ranks below CUSTOMER and can assign nothing at all.

Portals

A person’s organization roles determine the highest portal they may activate; they may then work at that level or any level below it.

Organization roleHighest portalPortals they can activate
platform administratorplatformplatform, msp, organization, customer
MSP administratormspmsp, organization, customer
MSP technicianmspmsp, organization, customer
organization administratororganizationorganization, customer
power userorganizationorganization, customer
CUSTOMERcustomercustomer

Switching portals re-mints the token from the person’s current memberships rather than trusting the presented token’s claim, so a role that was removed cannot be carried forward through a portal switch.


Walkthrough — giving someone administrator rights

Administrator rights are the organization role, not a job-function role.

  1. Go to Users in the sidebar (/org/users).
  2. Open the person and select the Permissions tab.
  3. Under Access level, pick the new role and click Change.

The dropdown offers only roles you may actually grant. The change takes effect the next time that person’s access token is minted — at their next refresh or portal switch — because the role travels in the token. Revoke their sessions if it must apply immediately.

Four refusals apply, and the control hides or disables itself for the first three rather than letting you hit them:

RefusalWhy
Cannot grant a role higher than your ownAn organization administrator cannot mint an MSP administrator; nobody but a platform admin mints one
Cannot change a person who holds a role higher than your ownA client’s admin cannot demote the MSP admin operating their workspace
You cannot change your own organization roleNo self-service, in either direction
Cannot remove the last administrator from this organizationThe organization always keeps at least one active administrator

To set the role at creation time instead, use Users → New user, which carries the same ceiling. The creation form does not accept platform administrator at all.

Change an MSP staff member’s access level from the organization portal, or through the API below.


Walkthrough — creating a custom role

A custom role is a named job function owned by one organization.

  1. Go to Administration → Roles in the sidebar (/org/settings/roles, or /msp/settings/roles).
  2. Click Create Role.
  3. Enter a display name (“Field Engineer”). The machine name is derived automatically and must be uppercase letters and underscores only — A–Z and _, nothing else.
  4. Optionally add a description.
  5. Click Create.

The role is created against your current organization, is never a system role, and cannot itself be cloned.

To see who holds a role, click View Users on its card. The list shows each holder, whether the assignment is their primary one, and whether it is active, revoked, or time-limited.


Walkthrough — cloning a system role

Cloning copies a shipped role and its permission set into your organization so you can adjust it without touching the shared original.

  1. Go to Administration → Roles.
  2. Find a role marked System — those with a Clone button are cloneable.
  3. Click Clone, give the copy a display name and machine name, and confirm.

The copy is independent. It records where it came from, but it does not inherit from it: later edits to the original do not reach the copy, and you can remove a permission from the copy that the original grants. (Until this release the clone was wired as a live subclass of its source, which meant a permission could never actually be removed from the copy — it fell back to the inherited one every time.)

You can only clone a role your account owns or a platform-wide system role. Another tenant’s role returns “Role not found”.


Job-function roles and what they drive

Thirteen system roles ship with the platform. They are shared by every tenant, carry a permission set, and are read by real product behaviour.

RolePermissions in the catalogue
SUPER_ADMIN241
ADMIN120
FINANCE67
MANAGER35
SENIOR_TECHNICIAN34
platform administrator27
SALES25
DISPATCHER21
TECHNICIAN19
ACCOUNTANT16
CLIENT_ADMIN14
CLIENT_USER8
JUNIOR_TECHNICIAN8

TECHNICIAN is the default role applied to new people.

What holding one of these actually does today:

ConsumerBehaviour
Asset-expiry and contract notificationsNotifies holders of ADMIN / MANAGER / TECHNICIAN
Platform staff administrationThe platform’s own staff ranks (see section 12)
Directory mapping (SCIM / identity provider)A synced directory group can be mapped to one org-owned custom role

What it does not do: the individual permission rows attached to a role (ticket:update, invoice:void, and 721 others) are not evaluated when a request is authorized. See Limits — this is the single most important caveat in this document.


Time-limiting and revoking an assignment

Every job-function assignment carries two lifetime controls:

ControlEffect
expiresAtAfter this moment the assignment stops counting, with no job to run
isActiveSet false to suspend the assignment without deleting it

Both are honoured everywhere an assignment is resolved: effective permissions, spend-approval routing, ticket-workflow role conditions, asset-expiry and contract-renewal notification targeting, the RBAC resolver’s user context, and organization-membership resolution. An expired assignment is still listed on the role’s View Users panel, marked Expired, so you can see and clean up what lapsed.


Directory-driven roles (SSO and SCIM)

MechanismWhat it sets
OAuthProvider.defaultOrgRoleThe organization role given to a person provisioned just-in-time at SSO login
SCIM group → role mapping (ScimGroup.roleId)Members of a synced directory group hold an org-owned custom role
Identity-provider mapping (IdentityProviderMapping.targetRoleId)Maps an identity provider user or group onto a job-function role

A directory group may only be mapped to a role the organization owns — never a system or platform staff role.


Platform staff roles

Tridacom’s own staff carry a fifth vocabulary, separate from tenants entirely, managed at /platform/staff.

Staff roleRank (lower is more privileged)
SUPER_ADMIN0
platform administrator1
BILLING_ADMIN2
SUPPORT_AGENT2
CATALOG_ADMIN2

A staff member cannot invite or promote anyone to a rank above their own. The caller’s own rank is resolved from their real assignment rows, not from their token — the token only carries the coarse platform administrator organization role needed for login. A caller with no staff assignment row is treated as platform administrator, the least-privileged rank the platform portal admits.


Account roles

The billing account has its own three-level role, used only for account administration.

Account roleCan do
OWNEREverything, including changing other members’ account roles
ADMINInvite members at ADMIN or MEMBER
MEMBERNothing administrative

An ADMIN cannot mint an OWNER. The last remaining OWNER cannot be demoted.


Plan tiers

Roles and permissions are not plan-gated. Every tier gets the full role administration surface, custom roles, cloning and assignment. What each tier limits is the number of people you can have.

Tier (MSP)Seats per organizationTier (End customer)Seats per organization
Free5Free3
Starter15Essentials10
Growth25Professional25
Scale50Business50
EnterpriseUnlimitedEnterpriseUnlimited

Single sign-on, which is how most organizations drive roles from a directory, is Enterprise-only on both tracks.


Troubleshooting

What you seeWhat it means
Insufficient roleThe route’s floor rejected you. If you are an MSP technician on a role-editing screen, that is by design
Portal access deniedRight role, wrong portal. Switch portals rather than changing the role
Organization is outside your accountThe target organization belongs to another tenant
Cannot modify platform-wide roles / Cannot delete platform-wide rolesThe role has no owning organization. Only a platform admin may touch it
Cannot modify permissions of system rolesClone it first, then edit the copy
Cannot modify inheritance of system rolesA system role’s parent is fixed
Cannot delete system rolesSystem roles are shared by every tenant
Cannot delete role with assigned usersRemove the holders first — deleting would leave people with a dangling assignment
Cannot delete a role that other roles inherit fromRe-parent or delete the children first
Role name already exists in this organizationMachine names are unique per organization
Cannot grant platform-administration permissions: …Only a platform admin may attach permissions on platform, account, service_tier, permission and the platform commerce resources
One or more permission ids do not existA stale permission id in the request
Fine-grained permission restrictions are not enforced by any service, so they cannot be saved. …You tried to save a per-assignment ticket-priority/category/asset-type restriction. Use the role’s scope instead
`Reading another person’s permissions requires organization administratorYou may always read your own
Cannot grant a role higher than your ownThe organization-role ceiling, or the account-role ceiling (OWNERADMINMEMBER)
Cannot change a person who holds a role higher than your ownDemotion carries the same ceiling as promotion
You cannot change your own organization roleAccess levels are changed by someone else, in both directions
Cannot remove the last administrator from this organizationPromote a replacement first
Role not found when cloningThe source role belongs to another tenant, or does not exist

Limits and known behaviour

Attached permissions are descriptive, not enforced. This is the important one. The catalogue holds 723 permissions across 55 resources, and the 13 system roles carry 635 grants between them — but no service consults those rows when deciding a request. Authorization is the four-step check in section 3: portal, organization role, route floor, tenant scope. Adding invoice:void to a custom role does not let its holders void invoices, and removing it does not stop them. Treat a role’s permission set as documentation of the job function, and use the organization role to control access. The API now refuses to let a non-platform-admin attach platform-administration permissions, so the catalogue cannot become an escalation path if enforcement is later wired up.

Custom roles are created with no permissions. Nothing in the web UI sets permissionIds, so a role created through the portal starts empty. Cloning is the only way to get a populated permission set. Given the point above, this affects the role’s description, not what its holders can do.

Per-assignment restrictions cannot be saved. TICKET_PRIORITY, TICKET_CATEGORY, ASSET_TYPE and REQUIRES_APPROVAL restrictions are modelled and were once persistable, but no service reads them. The API rejects a non-empty restriction list rather than confirm a control it would not apply. Clearing to [] is still accepted so old rows can be removed.

Role changes do not invalidate a live token. The organization role is a token claim, so a demotion takes effect at the next token mint (refresh, portal switch, or re-login). Revoke the person’s sessions if the change must be immediate.

A route that acts on a different organization taken from the URL or body must also constrain its query with accountScope — the role floor alone would let someone privileged in their own organization act on another.

The resolver caches for five minutes, per process. A role’s resolved permission set is memoised in-process for 5 minutes. Editing a role or its permissions clears that cache in the service that handled the edit; other service instances pick the change up when their entry lapses.

The membership role they may set is still capped at their own tier.

Global roles need a platform admin. Only platform administrator can edit or delete a role with no owning organization, including renaming the shared system roles.

Questions this guide did not answer?

Ask us. You will get a reply from someone who uses the product every day.

Book a demo Contact us

A 30-minute walkthrough against your own workflow. No slides.