Skip to main content
RunBook Academy

Proxmox VEXIII · Proxmox Backup ServerPBS security

PBS users, ACLs, tokens and datastore permissions

Advanced⏱ ~26 minproxmox-backup-manager

What you'll learn

  • Navigate the PBS object-path tree and predict the effective permission at any path
  • Choose the right built-in role for a PVE cluster, an auditor and a sync partner
  • Create API tokens and explain why a token can never exceed its user
  • Build the append-only arrangement that stops a compromised PVE node deleting its own backups

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.

Most Proxmox estates add PBS to the cluster with a root@pam credential because that is what the setup guide shows and it works immediately. It is also the configuration in which an attacker who gets root on any node of the cluster can delete every backup of every guest, and then encrypt the guests.

The permission model is the control that prevents that, and it is the only one that survives a fully compromised hypervisor. Firewall rules, network segmentation and immutable-storage claims all help, but if the credential stored on the compromised node can prune the datastore, they help less than you think.

This lesson is therefore organised around one question: what can the credential on your PVE node actually do to the datastore?

The object-path tree

PBS addresses everything it protects with filesystem-like paths. Permissions are granted by attaching a role to a path for an authentication identity.

PathCovers
/Everything
/datastoreAll datastores
/datastore/{store}One datastore
/datastore/{store}/{ns}One namespace inside a datastore
/remoteAll configured remotes
/system/networkHost network configuration
/tape/Tape devices, pools and jobs
/access/usersUser administration
/access/openid/{id}A specific OpenID realm

Permissions granted at a shorter path can propagate down the tree:

Permissions of higher levels (shorter paths) can optionally be propagated down within this hierarchy.

The propagate flag defaults to enabled. That default is convenient and it is where over-permissioning creeps in: DatastoreAdmin on /datastore with propagation on is a grant over every datastore that exists and every one created later.

The roles, and what each is for

RoleGrantsUse it for
NoAccessNothingExplicitly denying a subtree below a broader grant
AdminAnything, on the object path assignedHuman administrators, scoped as narrowly as the job allows
AuditView status and configuration; change nothingMonitoring systems, auditors, junior on-call
DatastoreAdminAnything on existing datastoresA backup administrator who should not create datastores
DatastoreAuditView metrics, settings and content listings; cannot read the actual dataCapacity dashboards and compliance evidence without data access
DatastoreReaderInspect a datastore or namespace and perform restoresA restore-only operator account
DatastoreBackupBack up and restore owned backupsThe PVE cluster credential
DatastorePowerUserBack up, restore and prune owned backupsA cluster that manages its own retention. Note what that implies
RemoteAdminAnything on remotesManaging the remote configuration
RemoteAuditView remote settingsMonitoring sync configuration
RemoteSyncOperatorRead data from a remoteThe account a pull sync job runs as
TapeAdmin / TapeOperator / TapeAudit / TapeReaderTape operations at descending privilegeTape workflows

The two rows that carry the whole security argument are DatastoreBackup and DatastorePowerUser. They differ by exactly one capability: prune.

Creating the accounts

Configuration changethe PVE cluster identity - a user, a token, one namespace
set -euo pipefail

# A dedicated user for the cluster, in the built-in PBS realm.
proxmox-backup-manager user create pve-cluster-a@pbs \
--comment 'Backup identity for production cluster A'

# A token belonging to that user. Tokens are what automation should carry;
# they can be revoked without disturbing the user or any other token.
proxmox-backup-manager user generate-token pve-cluster-a@pbs backup
# => { "tokenid": "pve-cluster-a@pbs!backup", "value": "REPLACE_ME_ONCE_ONLY" }

# Grant on the namespace only, not the datastore.
proxmox-backup-manager acl update /datastore/store1/prod-cluster-a \
DatastoreBackup --auth-id 'pve-cluster-a@pbs!backup'

# The token needs the grant; so does the user, because the effective
# permission is the intersection of the two.
proxmox-backup-manager acl update /datastore/store1/prod-cluster-a \
DatastoreBackup --auth-id 'pve-cluster-a@pbs'
Read-only / Safecheck what an identity can actually do, rather than what you meant
# proxmox-backup-manager user permissions 'pve-cluster-a@pbs!backup' --path /datastore/store1/prod-cluster-a
Privileges with (*) have the propagate flag set

Path: /datastore/store1/prod-cluster-a
- Datastore.Backup (*)
- Datastore.Read (*)

Illustrative output

Wiring it into PVE

Configuration changeadd the PBS storage on the PVE side using the token
set -euo pipefail

# On the PBS server:
#   proxmox-backup-manager cert info | grep -i fingerprint

pvesm add pbs pbs-main \
--server pbs1.example.com \
--datastore store1 \
--namespace prod-cluster-a \
--username 'pve-cluster-a@pbs!backup' \
--password 'REPLACE_ME_ONCE_ONLY' \
--fingerprint 'aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99' \
--content backup

pvesm status --storage pbs-main
Configuration changeretention on the server side, where the cluster cannot reach it
set -euo pipefail

proxmox-backup-manager datastore update store1 \
--prune-schedule 'daily 04:00' \
--keep-daily 14 --keep-weekly 8 --keep-monthly 12

proxmox-backup-manager datastore update store1 --gc-schedule 'sat 03:00'

Roles for the other actors

ActorPathRoleReasoning
PVE production cluster/datastore/store1/prod-cluster-aDatastoreBackupWrite and restore its own; never delete
Monitoring / dashboards/datastoreDatastoreAuditNeeds usage and job status; must not be able to read backup contents
Restore-only operator/datastore/store1DatastoreReaderCan inspect and restore anything; cannot write or prune
Backup administrator/datastoreDatastoreAdminFull control of existing datastores, no host administration
Pull sync from a remote/remote/{remote}/{store}RemoteSyncOperatorRead the remote; the local write privilege is granted separately
Standalone host client/datastore/store1/hostsDatastoreBackupSame argument as the cluster, at host granularity

Sync jobs deserve a note because their privileges are split across two sides. A pull job needs Remote.Read on /remote/{remote}/{remote-store} plus Datastore.Backup on the local target, and additionally Datastore.Prune if it uses remove-vanished. A push job needs Remote.Audit and Remote.DatastoreBackup on the target, plus read or backup privileges on the source, and Remote.DatastorePrune for remove-vanished.

Knowledge check

Knowledge check · 4 questions

  1. Q1. A newly created API token authenticates but every operation is denied, while the owning user has DatastoreAdmin on the datastore. What is the cause?

  2. Q2. A PVE cluster credential is given DatastoreBackup on its namespace instead of DatastorePowerUser. What changes? Select all that apply.

  3. Q3. DatastoreAudit is a suitable role for a monitoring system that should report datastore usage and job status without being able to read backup contents.

  4. Q4. Which sync direction leaves the primary site holding no credential that can write to the off-site copy?

Passing score: 75%. Answers are checked in this browser.