Proxmox VEXXV · Proxmox Datacenter ManagerSecurity and boundaries
Access control and the trust boundary
What you'll learn
- Describe PDM realms, its three built-in roles, and why least privilege in PDM is expressed through paths
- Explain the two-layer authorisation model: the PDM ACL, then the remote-side token privileges
- Identify what the cluster audit trail can and cannot tell you about who acted through PDM
- Assess the PDM host as a concentration of blast radius and scope the remote token accordingly
- Plan token rotation, secret handling and separation of trust zones across PDM instances
Prerequisites
Verified against Proxmox VE 9.2.4 · Proxmox Backup Server 4.2.5 · Ceph Squid / Tentacle · Debian 13 (Trixie) · Linux kernel 7.0 (PVE 9.2 default) · 2026-08-12
Two courses in this academy have already taught this shape.
The Ansible course spends a whole part on the proposition that the controller is the fleet: a single machine holding credentials that reach every server, where a compromise is not “one host” but “everything that host can log into”. The Linux course teaches the same arithmetic about central identity and secrets — that centralising authentication buys you revocation and consistency at the price of a target whose value is the sum of everything behind it.
PDM is that shape again, arriving through a door marked convenience. It holds a privileged API token for every cluster you manage, in a file, on one host, so that a dashboard can load quickly.
This lesson is about designing for that deliberately.
PDM’s own authentication
PDM authenticates its own users through realms, chosen when the user is added:
| Realm | Source |
|---|---|
pam | Linux PAM; the user must already exist on the PDM host |
pdm | PDM’s own realm; hashed passwords in /etc/proxmox-datacenter-manager/access/shadow.json |
ldap | An external LDAP server |
ad | An external Active Directory server |
openid | An external OpenID Connect server |
root@pam is the superuser with full administration rights on everything, and
the documentation recommends adding other users with fewer privileges rather
than working as root. That recommendation is doing more work in PDM than it
does in PVE, for reasons the next section makes clear.
Two-factor authentication supports TOTP, WebAuthn, and single-use recovery keys. The documentation makes the point that you should set up multiple second factors so that losing a phone or a security key does not lock you out permanently, and that recovery keys should be printed and locked away or held in an electronic vault.
Three roles, and no custom roles
Here is where PDM diverges sharply from PVE, and where most people’s mental model breaks.
PDM’s privileges are the building blocks used to enforce API permission checks:
| Privilege | Allows |
|---|---|
System.Audit | Knowing about the system and its status |
System.Modify | Modifying system-level configuration |
Sys.Console | Access to the system console |
Sys.PowerManagement | Powering off or rebooting the system |
Resource.Audit | Auditing guests, storages and other resources |
Resource.Manage | Managing resources, such as starting or stopping guests |
Resource.Modify | Modifying resources, such as configuration changes |
Resource.Create | Creating a guest |
Resource.Delete | Deleting a guest |
Resource.Migrate | Remote migration of a guest |
Access.Audit | Auditing permissions and users |
Access.Modify | Modifying permissions and users |
Realm.Allocate | Viewing, creating, modifying and deleting realms |
A role combines privileges into something assignable. And the roles are:
NoAccess— nothing is allowed.Administrator— can do anything, on the object path assigned.Auditor— can view status and configuration, but not change settings.
That is the complete list. The documentation states plainly that there are currently only built-in roles, meaning you cannot create your own custom role.
Paths, propagation and the ACL file
Objects are addressed with filesystem-like paths that form a tree, and permissions on shorter paths can propagate down it. The documented paths:
| Path | Scope |
|---|---|
/resource | All resources managed by PDM |
/resource/{id} | Resources on a specific remote |
/resource/{id}/guest | All guest resources on a specific remote |
/resource/{id}/guest/{vmid} | One specific guest on a specific remote |
/resource/{id}/node | All node resources on a specific remote |
/resource/{id}/node/{name} | One specific node on a specific remote |
/views/ | Views |
/views/{id} | A specific view |
/system/network | Host network configuration |
/access/users | User administration |
/access/domains | Administrative access to realms |
Two inheritance rules govern the tree. Permissions on deeper, more specific
levels replace those inherited from an upper level — so an Auditor grant
on /resource plus an Administrator grant on /resource/site-lab gives read
everywhere and full control on site-lab, which is the composition you usually
want. And permissions for API tokens are always limited to those of the user
they belong to.
The stored form lives in /etc/proxmox-datacenter-manager/access/acl.cfg as
five colon-separated fields — the literal acl identifier, a propagation flag
of 1 or 0, the object path, the user or token, and the role:
acl:1:/resource/site-lab:alice@pdm:Administrator
acl:1:/views/noc-overview:noc@pdm:Auditor
acl:0:/resource:reporting@pdm!weekly:Auditor
Manage these through Configuration, then Access Control, then Permissions in the
web interface, or with proxmox-datacenter-manager-client acl update and
acl delete from the CLI. Reading the file directly is the fastest way to
answer “who can do what here” during a review.
# proxmox-datacenter-manager-client acl list --output-format textPDM’s API tokens
Any authenticated user can generate API tokens. The identifier is
user@realm!tokenname and the secret is separate; both are supplied by the
client in place of the user ID and password, passed in the Authorization
header with the method PDMAPIToken and the value TOKENID:TOKENSECRET.
The permission model has two rules that are worth memorising because they are different from what people assume:
- Tokens require their own ACL entries. A token’s permissions are computed from ACLs containing the token’s ID, independently of the user’s. A new token with no ACL entry can do nothing, no matter how privileged its user is.
- Tokens can never do more than their user. The token’s computed permission set on a path is intersected with the user’s.
That is a good design: the first rule makes tokens opt-in rather than inheriting, and the second makes revoking the user revoke everything they issued.
The two-layer authorisation model
Now the part that is easy to get wrong.
When an operator clicks Start on a guest in PDM, two authorisation checks happen, in different systems, against different identities.
flowchart LR
U[PDM user alice@pdm] -->|check 1: PDM ACL on /resource/site-a/guest/141| P[PDM]
P -->|acts as the remote token| T["pdm@pve!datacenter-manager"]
T -->|check 2: PVE ACL for that token| C[site-a cluster]
C --> G[VM 141 starts]
Check one is PDM’s own ACL: may alice@pdm perform this action on this
path? That is the table above.
Check two happens on the cluster. The Guests chapter says it directly: the guest list shows the resources the user may audit, and every action is carried out against the backing remote, where the remote’s own privileges apply — so an operator needs the appropriate permission on the target guest’s remote for an action to succeed.
But the identity presented at check two is not alice@pdm. It is the
single API token you configured in remotes.cfg for that remote. Every PDM
user shares it.
The intersection has one more consequence that catches people out. Because the remote-side token is shared, the remote’s ACL cannot distinguish between PDM users. Scoping a PDM user to one remote works, because PDM enforces it. Scoping them to one guest works, because PDM enforces it. But every one of those boundaries is enforced by PDM alone. The cluster’s own permission system is providing a ceiling for all PDM activity, not a per-user boundary.
So the remote-side token privilege is the single most important number in this
design: it is the maximum damage any PDM path can do, and the last line of
defence if PDM’s own ACL is bypassed by a bug, a misconfiguration, or somebody
holding root@pam.
Where the secrets sit
/etc/proxmox-datacenter-manager/ is the whole trust store:
| File | Contains |
|---|---|
remotes.cfg | Per remote: authid, the token secret, node addresses, type |
access/shadow.json | Hashed passwords for pdm realm users |
access/acl.cfg | Every permission grant |
auth/api.pem | The PDM API certificate and key |
views.cfg | View definitions |
remotes.cfg is the one that matters. It holds a usable credential for every
cluster in your estate, and the schema documents token simply as “The access
token’s secret” — a value, in a configuration file, on a host.
Everything the Linux course teaches about secrets at rest and file modes applies to this directory without modification, and three things follow specifically:
- Backups of this directory are secret-bearing artefacts. Encrypt them, restrict them, and hold them to the same standard as a password vault export. A PDM backup on a general-purpose file share is a credential leak with extra steps.
- Anyone with root on the PDM host has your estate. Not “can log into PDM” — has the tokens, and can use them from anywhere. The PDM host’s own hardening, patching and access control is therefore cluster-grade work, not utility-VM work.
- A shell on the PDM host is a lateral-movement jackpot. Which is a reason
to be careful about who gets
Sys.Consolein PDM, and about the Administration Shell in the interface.
Key takeaways
- PDM authenticates users through
pam,pdm,ldap,adandopenidrealms, and supports TOTP, WebAuthn and recovery keys. - There are three roles —
NoAccess,Administrator,Auditor— and no custom roles. Least privilege is expressed by choosing the path, not the role. - PDM API tokens need their own ACL entries and are always intersected with their user’s permissions.
- Every action is authorised twice: by PDM’s ACL against the PDM user, then by the cluster against a single shared remote token.
- The cluster’s audit trail names the token, not the person. Attribution lives only in PDM’s log, which makes PDM log retention an audit control.
- The remote-side token privilege is the ceiling on all PDM activity and the last defence if PDM’s ACL is bypassed. Scope it to the feature level you chose deliberately.
remotes.cfgholds a usable credential for every cluster. Root on the PDM host, or a copy of its backup, is the estate.
Knowledge check
Knowledge check · 4 questions
Q1. An operator needs to start and stop guests on the site-lab remote through PDM, but must not be able to delete them. What does PDM 1.1.7 let you configure?
Q2. VM 141 on site-a was stopped through PDM at 14:07 during an incident review. Which statements about the audit trail are correct? Select all that apply.
Q3. A newly created PDM API token belonging to a user who holds Administrator on /resource can do nothing at all until an ACL entry is created that names the token itself.
Q4. You are hardening a PDM deployment and must decide the privilege level of the API token PDM holds on each PVE cluster. Which consideration should drive the decision?
Passing score: 75%. Answers are checked in this browser.