Skip to main content

ACL v2 / RBAC (REST API/XO6)

ACL v2 is the access control system for the Xen Orchestra REST API and the XO6 UI. It lets you define exactly what each user or group can see and do — down to individual objects — without granting them full administrator access.

What changed from v1

The old ACL system (v1) allowed granting access to individual objects (a VM, an SR…). Simple, but limited: there was no way to say "this user can shutdown only VMs tagged qa". It also only covered XAPI objects — VMs, hosts, SRs, networks. Users, groups, backups, schedules, and jobs were out of scope.

ACL v2 introduces a full RBAC (Role-Based Access Control) model with effects, selectors, and an action hierarchy, covering the entire infrastructure including XO management objects.

note

ACL v2 is available through the REST API only. The JSON-RPC API (used by XO5) stays on ACL v1. Conversely, ACL v1 is not available on the REST API.


Core concepts

How it works

ACL v2 follows a deny-by-default model:

  • XOA admins always have full access, regardless of any ACL configuration.
  • Non-admin users start with zero access. They can only access objects they have been explicitly granted permission to.
  • A deny privilege always takes precedence over an allow privilege on the same action + resource + object combination.

The system is built around two building blocks:

ConceptDescription
RoleA named container for privileges.
PrivilegeA rule inside a role: which action is allowed (or denied) on which resource, and optionally on which subset of objects.

Roles

A role is just a label with a collection of privileges. You create a role once, add privileges to it, then assign it to as many users or groups as needed.

A user's effective privileges are the union of all privileges from all their direct roles and the roles of their groups.

Privileges

A privilege defines:

  • resource — the type of object (e.g. vm, backup-job, sr)
  • action — what operation is allowed or denied (e.g. read, start, delete)
  • effect — whether the privilege grants (allow) or blocks (deny) the action
  • selector (optional) — a filter expression to restrict the privilege to a subset of objects (complex-matcher format)

Action hierarchy

Actions use a : separator to form a hierarchy. A broader action automatically covers its children:

Privilege actionCovers
shutdownshutdown:clean and shutdown:hard
rebootreboot:clean and reboot:hard
updateupdate:tags, update:datasources, …
*every action on the resource

The reverse is not true: granting shutdown:clean does not grant shutdown:hard.


Built-in template roles

Xen Orchestra ships with four ready-to-use role templates. They are immutable and automatically kept up to date on startup — they cannot be modified, deleted, or assigned directly.

To use them, copy a template into a new role and assign that copy to your users or groups. This ensures the built-in templates always stay up to date without affecting your custom configuration.

RoleDescription
Read onlyRead access to the entire infrastructure and all XO objects. Cannot modify anything.
VMs power state managerCan start, stop, reboot, pause, suspend, resume, and unpause VMs.
VMs creatorCan instantiate VM templates and create VDIs and VIFs.
VMs read onlyCan only list and view VMs.

acl-role copy documented in Swagger


Self endpoints

Some endpoints are always accessible to a logged-in user without any ACL privilege, as they only expose information about the user themselves:

EndpointDescription
GET /rest/v0/users/meGet your own user profile
GET /rest/v0/users/me/privilegesList your own privileges
GET /rest/v0/users/me/authentication_tokensList your own authentication tokens
POST /rest/v0/users/me/authentication_tokensCreate an authentication token for yourself

me is a convenience alias — it is automatically redirected to /rest/v0/users/{your-id}.

tip

The Swagger UI available at /rest/v0/swagger documents every endpoint with its required privileges. Endpoints with no declared privilege are admin-only.


Supported resources and actions

Actions are written using the exact string you pass in a privilege. A parent action (e.g. reboot) is a shortcut that covers all its children — see Action hierarchy.

Infrastructure resources

ResourceAvailable actions
vmread, delete, export, pause, start, resume, snapshot, suspend, unpause, reboot:clean, reboot:hard, shutdown:clean, shutdown:hard, update:datasources, update:tags
vm-snapshotread, delete, export, update:tags
vm-templateread, delete, export, instantiate, update:tags
vm-controllerread, update:tags
vdiread, create, delete, boot, export-content, import-content, update:tags
vdi-snapshotread
vdi-unmanagedread
vifread, create
vbdread
srread, import:vdi, import:vm, update:tags
hostread, allow-vm, export:logs, update:tags
poolread, emergency-shutdown, rolling-reboot, rolling-update, create:network, create:vm, update:tags
networkread, create, delete, update:tags
pifread
pbdread
pciread
pgpuread
vgpuread
vgpuTyperead
vtpmread
smread
gpuGroupread

XO management resources

ResourceAvailable actions
backup-jobread
backup-archiveread
backup-logread
backup-repositoryread
scheduleread, run
restore-logread
proxyread
serverread, create, delete, connect, disconnect
taskread, abort, delete
alarmread
messageread

User management resources

ResourceAvailable actions
userread, create, delete, update:name, update:password, update:permission, update:preferences
groupread, create, delete, update:name, update:users
acl-roleread, create, delete, update:name, update:description, update:users, update:groups
acl-privilegeread, create, delete, update:action, update:effect, update:resource, update:selector

Concrete examples

Alice: QA operator scoped to tagged VMs

Alice needs to start and stop VMs in her test environment, but must not touch anything in production.

Create a QA Operator role with these privileges:

{ "resource": "vm", "action": "read", "effect": "allow", "selector": "tags:qa" }
{ "resource": "vm", "action": "start", "effect": "allow", "selector": "tags:qa" }
{ "resource": "vm", "action": "shutdown", "effect": "allow", "selector": "tags:qa" }

Attach the role to Alice. She can now manage QA VMs only. Any attempt on a VM without the qa tag is blocked with a 403.

Selectors are evaluated dynamically

If someone adds the qa tag to an existing VM, it immediately appears in Alice's scope. This means a single tag change is enough to grant or revoke access to a resource, with no need to touch roles or privileges at all.


Bob: Snapshot only running VMs

Bob is allowed to snapshot VMs, but only while they are running — to avoid snapshotting stopped VMs that may be part of an automated maintenance process.

Create a Running VM Snapshot role with these privileges:

{ "resource": "vm", "action": "read", "effect": "allow", "selector": "power_state:Running" }
{ "resource": "vm", "action": "snapshot", "effect": "allow", "selector": "power_state:Running" }

Bob can see and snapshot any running VM. Stopped VMs are completely invisible to him.


Carol: Full VM access except production

Carol can do everything on VMs — except touch anything tagged prod.

Create a Full VM Access (non-prod) role with these privileges. The * wildcard grants every action on a resource at once. Pair it with a deny to carve out an exception — deny always wins:

{ "resource": "vm", "action": "*", "effect": "allow" }
{ "resource": "vm", "action": "*", "effect": "deny", "selector": "tags:prod" }

Carol can start, stop, delete, snapshot any VM she wants. Production VMs are completely invisible to her — they never appear in her lists and any direct attempt returns a 403.


Walkthrough: creating and assigning a role

Step 1 — Create a role

acl-role create documented in Swagger

Response:

{ "id": "e4b1f3c2-1234-5678-abcd-000000000001" }

Step 2 — Add privileges to the role

acl-privilege create documented in Swagger

Step 3 — Assign the role to the user

add user to role documented in Swagger

The user can now list VMs.

To assign to a group instead (all group members inherit the role):

add group to role documented in Swagger


Selectors

By default, a privilege applies to all objects of the given resource type. The optional selector field narrows it down using the complex-matcher syntax — the same filter syntax used in the XO UI.

A selector is evaluated against each object's properties. If it matches, the privilege applies; otherwise it does not.

Common selector patterns

GoalSelector example
A specific object by its IDid: <uuid>
All objects in a pool$pool: <pool-uuid>
VMs tagged with a labeltags: <tag>
VMs by power statepower_state: Running
VMs created by a specific usercreation:creator: <user-id>

Tips

  • Start minimal. Add only the privileges a user actually needs. It is easy to add more later.
  • Use groups. Assigning a role to a group avoids repeating the same assignment for every user.
  • Combine allow and deny. When a user needs broad access with specific exceptions, grant with a wildcard privilege and carve out exceptions with deny + a selector.
  • Template roles are immutable. Copy them first before customizing.
  • Endpoint permissions are visible in the Swagger UI (/rest/v0/swagger). Endpoints without a declared privilege require admin access.