Skip to content

Roles and permissions

Admin, Roles (/admin/roles), gated by the role.manage permission.

A role is a named set of permissions. Users hold one or more roles, and their effective permissions are the union.

A role holding * is a superuser within its tenant. Not across tenants: there is no permission anywhere that crosses a tenant boundary.

Roles are listed down the side, each with how many people hold it. Select one to see its grants grouped by area (Tickets, Repairs & charges, Devices, Identity, Administration and so on), each with a readable name beside the exact permission key. Editing a role uses the same areas; saving shows the grants for review first, because saving replaces the role’s whole permission set.

A role’s permissions also decide the seat type of everyone who holds it. Granting a role that raises someone’s seat says so in the role step on the Users page, and never blocks the grant.

Create the roles, then create the users. Doing it the other way means editing every account when you realise the role was wrong.

A shape that works for most schools:

Role Holds For
Administrator * You, and one other person
Technician View and update everything operational; issue and return loans; create, update and close repairs and tickets; view costs Your day-to-day staff
Senior technician Technician, plus device.manage, directory.manage, charge.approve, report.manage Whoever is trusted with MDM commands and money
Front desk loan.view, loan.issue, loan.return, repair.view, repair.create, client.view, stock.manage A counter that hands things out but does not fix them
Read only The .view permissions A head of department who wants visibility
Agentforce pilot client.view, assistant.agentforce.use Selected staff authorised for the Salesforce execution identity’s data; requires the upcoming advisory connector pilot
Operations coordinator operations.view, operations.manage Projects, maintenance, events, purchasing and shared resources
Operations approver operations.view, operations.approve Staff assigned to approve spending or change plans
Ticket approver ticket.view, approvals.view, approvals.decide Staff assigned to approve requests within their department and campus

The front desk role is the one worth building even in a small school. It is what lets you put a student helper or a casual on the counter during the first week of term without giving them the directory or the audit log.

The complete, current set of permission keys — grouped by area, with what each one allows — lives on one page so it cannot drift out of sync with itself: the permissions reference. That page is generated against packages/core/src/permissions.ts and checked for parity with it, so it is the page to build roles from.

Two splits are worth knowing about before you build a role:

ticket.internal is split out on purpose. An internal note is where somebody writes “third time this term, escalate” or “her mother rang, do not put this in writing”. Separating it means a school can hand a casual the queue without handing them that.

charge.raise and charge.approve are split across two people on purpose. A technician who can propose a charge must not be able to make it real, and the person who decides a family pays is the same person who can decide they do not, so waiving sits with approval rather than with raising. See damage charges.

The same checks run on every surface:

  • The web console.
  • The public REST API, scoped to the API key.
  • The MCP server, where a key without a permission does not even see the corresponding tool in tools/list.
  • The assistant, which can only do what the signed-in user’s role allows.

There is no ambient administrator and no back door for an integration. An API key is a set of scopes, and it cannot exceed them.

device.wipe.approve makes a wipe happen. That command destroys a student’s data and cannot be undone — it is split from device.wipe.request so the person who asks for a wipe is not, by default, the person who can also make it happen.

Live identity actions use separate permissions, including identity.password.reset, identity.mfa.reset and identity.mailbox.delegate. Re-enabling an account requires both identity.account.manage and identity.account.enable; granting Full Access also requires identity.mailbox.fullaccess. These operations can change who controls an account. Grant them selectively and record the reason and related ticket. directory.manage covers the older directory workflow and does not replace these live-action permissions.

Permission-gated actions are written to the audit log with who did it, when, and what changed. Reviewing that log once a term shows which permissions are in use, which is often narrower than what people asked for.

The 0.12.0-rc.3 candidate records covered directory actions and guarded live identity operations, with demo results labelled as such. Confirm the installed version and deployment status. Audit coverage is not complete for every operation; see coverage limits. A linked ticket preserves the reason for an action in addition to its audit record.