Skip to content

Permissions Tutorial

OpenIDCS implements RBAC (Role-Based Access Control) with additional resource-level and action-level granularity. This tutorial shows how to design roles, assign permissions and enforce them in API calls.

Permission Model

mermaid
graph LR
    U[User] -->|belongs to| R[Role]
    R -->|contains| P[Permission]
    P -->|applies to| O[Resource]
    U -->|extra policy| ACL[Object ACL]

Core concepts:

ConceptDescription
PermissionSmallest unit, e.g. vm:create
RoleA permission bundle, e.g. operator = {vm:*, net:read}
PolicyAdditional rules stacked on a user or role
ACLAccess list for a specific object (one VM)

Permission Catalog

Naming rule: <module>:<action>, where * means all actions.

VM module (vm)

PermissionDescription
vm:createCreate VMs
vm:readView VM info
vm:updateModify config (CPU/Mem/Disk/NIC)
vm:deleteDelete VMs
vm:powerPower ops (start/stop/reboot/suspend)
vm:consoleAccess console / terminal
vm:snapshotSnapshot management
vm:backupBackup and restore
vm:migrateMigrate to another host
vm:*All of the above

Host module (host)

PermissionDescription
host:readView host list and metrics
host:createAdd an agent host
host:updateModify host parameters
host:deleteRemove a host
host:manageMaintenance mode, restart agent

Network module (net)

PermissionDescription
net:readView IP pools, port forwards, proxy rules
net:natConfigure NAT port forwarding
net:proxyConfigure Web reverse proxy
net:firewallConfigure firewall rules
net:ippoolManage IP pools

User / RBAC module (user / rbac)

PermissionDescription
user:readView user list
user:createCreate users
user:updateUpdate account info / quota
user:deleteDelete users
rbac:manageManage roles, permissions and policies

System module (sys)

PermissionDescription
sys:configModify global settings
sys:logView logs
sys:auditView audit log
sys:backupSystem-level backup

Built-in Roles

RolePermissionsIntended For
admin*:* (everything)System administrator
operatorvm:*, host:read, net:read, net:nat, net:proxyOps engineer
uservm:create, vm:read, vm:update, vm:delete, vm:power, vm:console, vm:snapshot, vm:backupRegular tenant
readonlyvm:read, host:read, net:read, sys:logAuditors / viewers
guestvm:read (own only)Temporary guest

Tip

Built-in roles cannot be deleted, but can be overridden — a custom role with the same name takes precedence.

Custom Roles

Create a Role

  1. Go to Permissions → Roles → Create Role.
  2. Fill in the identifier (e.g. backup-operator) and description.
  3. Tick the required permissions in the permission tree:
    ✅ vm:read
    ✅ vm:backup
    ✅ vm:snapshot
    ✅ sys:log
  4. Click Save.

Clone a Role

To tweak an existing role:

  1. Open the role detail → Clone as New Role.
  2. Rename it, adjust permissions, save.

Assign a Role

Under User Management → User Detail → Roles:

  • Primary role: single select, decides default permissions
  • Additional roles: multi-select, permissions are unioned

Manage Roles via API

bash
# Create a role
POST /api/rbac/role
{
  "name": "backup-operator",
  "desc": "Operator who only manages backups",
  "permissions": ["vm:read", "vm:backup", "vm:snapshot", "sys:log"]
}

# Assign roles to a user
POST /api/user/alice/roles
{ "roles": ["user", "backup-operator"] }

Object-level ACL

On top of role permissions, OpenIDCS lets you grant access to a specific instance:

  1. VM detail page → Share & Authorize.
  2. Add collaborators and pick a permission set:
    bob   → read-only
    carol → power ops (power + read)
    dave  → full control (all except delete)
  3. The authorized user will see the shared instance in their own list.

Note

Object-level ACL can only narrow, never widen: if the user's role lacks vm:read, granting read on a specific VM still has no effect.

Policy

For more complex conditions use policy expressions:

yaml
# Example: only allow power/update on prod VMs during working hours
name: production-hours
effect: allow
actions: ["vm:power", "vm:update"]
resources: ["vm:prod-*"]
conditions:
  time:
    weekday: [1,2,3,4,5]
    hour: [9, 18]
  ip:
    cidr: ["10.0.0.0/8"]

Fields:

FieldDescription
effectallow or deny
actionsList of permissions, supports wildcards
resourcesResource match, supports prefix / regex
conditionsOptional: time, IP, MFA state, etc.

Priority

deny outranks allow: if any applicable policy denies, access is refused.

Host ACL

Under User Management → Host ACL tick which hosts a user may use. This is a coarse, physical isolation layer:

  • Tick docker-01 → user can only create / view / operate instances on docker-01
  • Leave empty → fall back to the global default (allow-all or deny-all, controlled by a global switch)

Authorization Flow

mermaid
flowchart TD
    Req[API request] --> Auth[AuthN: Token/Session]
    Auth --> Q1{User exists & enabled?}
    Q1 -- No --> Deny[401 Unauthorized]
    Q1 -- Yes --> Roles[Load roles & policies]
    Roles --> Q2{Explicit deny?}
    Q2 -- Yes --> Forbid[403 Forbidden]
    Q2 -- No --> Q3{Any allow?}
    Q3 -- No --> Forbid
    Q3 -- Yes --> Q4{Host & object ACL allow?}
    Q4 -- No --> Forbid
    Q4 -- Yes --> Pass[Allow]

Common Scenarios

Scenario 1: Read-only auditor

Role: auditor
Permissions: vm:read, host:read, net:read, sys:log, sys:audit
Host ACL: all hosts
Quota: 0 (no resource creation)

Scenario 2: Ops engineer that cannot delete

Base role: operator
Additional deny policy:
  actions: ["vm:delete", "host:delete"]
  resources: ["*"]

Scenario 3: Isolated R&D tenant

Role: user
Host ACL: dev-lxd-01, dev-docker-01
Quota: 20 vCPU / 40 GB RAM / 1 TB disk / 20 instances

FAQ

Why don't my permission changes take effect immediately?

A token's permissions are snapshotted at issue time. To make changes effective right away:

  1. Revoke the user's existing tokens and force re-login.
  2. Wait for the token to expire naturally (default 24 h).

You can also enable "broadcast permission change" in the System Settings — the backend will push a refresh to the frontend.

I accidentally deleted a custom role

  • Built-in roles cannot be deleted, so that's never an issue.
  • Deleted custom roles land in the Recycle Bin for 7 days.
  • After that, restore from a database backup (see Server Setup → Backup).

User can see a VM but not access its console

Check whether the user/role has vm:console. Viewing and console are separate permissions.

See Also

Released under the AGPLv3 License.