Skip to main content
RunBook Academy

Proxmox VEXXV · Proxmox Datacenter ManagerSecurity and boundaries

Access control and the trust boundary

Advanced⏱ ~32 minproxmox-datacenter-manager-clientpveum

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

Not yet marked complete on this device.

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:

RealmSource
pamLinux PAM; the user must already exist on the PDM host
pdmPDM’s own realm; hashed passwords in /etc/proxmox-datacenter-manager/access/shadow.json
ldapAn external LDAP server
adAn external Active Directory server
openidAn 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:

PrivilegeAllows
System.AuditKnowing about the system and its status
System.ModifyModifying system-level configuration
Sys.ConsoleAccess to the system console
Sys.PowerManagementPowering off or rebooting the system
Resource.AuditAuditing guests, storages and other resources
Resource.ManageManaging resources, such as starting or stopping guests
Resource.ModifyModifying resources, such as configuration changes
Resource.CreateCreating a guest
Resource.DeleteDeleting a guest
Resource.MigrateRemote migration of a guest
Access.AuditAuditing permissions and users
Access.ModifyModifying permissions and users
Realm.AllocateViewing, 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:

PathScope
/resourceAll resources managed by PDM
/resource/{id}Resources on a specific remote
/resource/{id}/guestAll guest resources on a specific remote
/resource/{id}/guest/{vmid}One specific guest on a specific remote
/resource/{id}/nodeAll 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/networkHost network configuration
/access/usersUser administration
/access/domainsAdministrative 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.

Read-only / Safethe whole authorisation picture in one command
# proxmox-datacenter-manager-client acl list --output-format text

PDM’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:

  1. 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.
  2. 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:

FileContains
remotes.cfgPer remote: authid, the token secret, node addresses, type
access/shadow.jsonHashed passwords for pdm realm users
access/acl.cfgEvery permission grant
auth/api.pemThe PDM API certificate and key
views.cfgView 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.Console in PDM, and about the Administration Shell in the interface.

Key takeaways

  • PDM authenticates users through pam, pdm, ldap, ad and openid realms, 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.cfg holds 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

  1. 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?

  2. 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.

  3. 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.

  4. 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.