Skip to content

Proxmox VE API permissions for PHP applications

The client works through the API, so an application can do exactly what its account is allowed to do, no more. Use a dedicated user with an API token rather than root@pam, and give it only the privileges the application needs.

Create a user and an API token, then assign a role with the privileges below, on / or on the smallest path that covers what the application touches (/vms/100, /pool/web, /storage/local).

The token to give to the client has the form automation@pve!app=<secret>: see Connection.

The built-in PVEAuditor role covers the *.Audit privileges: enough for an application that only reads. For anything else, create a role with just the privileges it needs from the table.

Privilege On Used for
VM.Audit /vms Reading VMs and containers: list, configuration, status, snapshots
Sys.Audit /nodes Reading nodes, and tasks started by other users
Datastore.Audit /storage Reading storage and its content
VM.PowerMgmt /vms Start, stop, shut down, suspend, resume, reset
VM.Snapshot /vms Taking, deleting and rolling back snapshots
VM.Config.* /vms Changing the configuration
VM.Backup /vms Backups, with Datastore.AllocateSpace on the storage
VM.Allocate /vms or /pool Creating VMs and containers, with Datastore.AllocateSpace on the storage
VM.Clone /vms Cloning, with VM.Allocate on the new id

The exact privilege of every endpoint is in the Proxmox VE API viewer, under Required permissions.

Proxmox VE answers a request the caller is only partly entitled to by filtering the response, not by failing it. /cluster/resources leaves out the guests, storages and pools the account cannot audit, and the VM list of a node leaves out the VMs without VM.Audit. Both return 200 OK: an empty list may mean a token without privileges, not an empty cluster.

A request that is refused outright returns a Result with status 403 and the reason in getReasonPhrase(), without throwing: see Errors.

A token can always read the tasks it started itself, so waiting for the task of your own call needs nothing more. Reading the tasks of other users needs Sys.Audit on the node: see Tasks.