Proxmox VE API permissions for JavaScript 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.
User and token
Section titled “User and token”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.
Privileges
Section titled “Privileges”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.
How missing privileges are reported
Section titled “How missing privileges are reported”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
reasonPhrase, 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.