Skip to content

Proxmox Permissions (Least Privilege)

Exactly which PVE privileges the panel needs, per feature — and how to grant them without handing over the farm.

Privilege matrix

Feature (panel side) PVE privilege(s) Used for
Connection test, version read (none beyond a valid token) GET /version works for any authenticated token.
Node discovery + node sync Sys.Audit GET /nodes, GET /nodes/{n}/status.
VM discovery + import + instance sync + metrics VM.Audit GET /cluster/resources?type=vm, GET /nodes/{n}/qemu, GET …/status/current.
Storage discovery/mapping Datastore.Audit GET /storage, GET /nodes/{n}/storage.
Network/template discovery Sys.Audit / VM.Audit GET /nodes/{n}/network; templates ride the VM resource list.
Power actions VM.PowerMgmt POST …/qemu/{vmid}/status/{cmd}.
Task (UPID) polling covered by the audits above GET /nodes/{n}/tasks/{upid}/status.
Future — VM creation VM.Allocate + Datastore.AllocateSpace POST /nodes/{n}/qemu, disk allocation.
Future — snapshots VM.Snapshot Snapshot create/rollback/delete.
Future — migration VM.Migrate POST …/migrate.
Future — console VM.Console VNC/serial ticket.

Not needed today (do not grant): VM.Config.*, VM.Backup, Datastore.Allocate, Realm.Allocate*, Permissions.Modify, anything Sys.Modify-adjacent.

Suggested role

pveum role add PteroCloud -privs "VM.Audit VM.PowerMgmt Datastore.Audit Sys.Audit"
pveum user add pterocloud@pve --comment "PteroCloud panel integration"
pveum acl modify / --users pterocloud@pve --roles PteroCloud
pveum user token add pterocloud@pve panel --privsep 0

Notes:

  • --privsep 0 (no privilege separation): the token inherits the user's ACLs exactly, so the PteroCloud role remains the single place to reason about. With --privsep 1 you must maintain privileges twice.
  • Path scoping narrows the blast radius: grant the role on /nodes/<node> (+ /storage/<id>) to confine the panel to one node, or on /vms/<vmid> for a single guest. Discovery is cluster-shaped, so a scoped token shows a partial inventory; the connection test reports that as failed steps, which is expected for a deliberately scoped token.
  • Read-only panels can drop VM.PowerMgmt and should also set the panel-side read_only flag.

Why not root@pam

  • A root@pam token is total: it can delete VMs, alter cluster membership, change authentication realms, and read every guest's config.
  • The panel stores token secrets (encrypted, but they exist to be used). Least privilege means a leaked or misused secret can enumerate and power-cycle VMs — and nothing else.
  • PVE API tokens are revocable independently of the user, so rotation does not touch any human's credentials.
  • Auditability: PVE task history attributes every action to pterocloud@pve!panel, never to a person.

How gaps surface

The panel surfaces gaps without failing hard: the connection test's permission inspector runs read-only probes and reports granted[]/missing[]/warnings[] — e.g. a missing VM.PowerMgmt shows up as a warning at test time instead of a surprise 403 on a customer's restart. Only an explicit 403 (or a readable permission map lacking the privilege) counts as "missing"; inconclusive probes become warnings.