infra-edge-lab · v0.1.0
0025. Proxmox VE API tokens with least privilege, instead of the root account
- Status: accepted
- Date: 2026-10-22
Context
The lab environment clones virtual machines on a Proxmox VE host through the bpg/proxmox
provider (ADR 0012). The provider can log in with a user
and password, with an API token, and for some features over SSH. The account that applies the lab
and the account that CI uses for read-only plans hold credentials that may leak: a token of
root@pam would give whoever has it the whole host, its storage and its network.
Considered options
root@pamwith its password, or an API token ofroot@pam.- One dedicated user with a broad built-in role (
PVEAdmin) on/. - Two dedicated users,
tofu@pve(apply) andci-plan@pve(plan), each with a privilege-separated API token, and a custom role granted only on the objects the lab uses.
Decision
Chosen option: 3, because a leaked token can then only do what the lab itself does.
- The provider talks to the API only: no
sshblock, no snippets and no file uploads, so no SSH account on the host is needed (tofu/modules/pve_vm). tofu@pvegets the roleTofuProvisionerwithVM.Allocate VM.Audit VM.Clone VM.Config.CDROM VM.Config.CPU VM.Config.Cloudinit VM.Config.Disk VM.Config.HWType VM.Config.Memory VM.Config.Network VM.Config.Options VM.PowerMgmt VM.GuestAgent.Audit Datastore.AllocateSpace Datastore.Audit SDN.Use Sys.Audit Pool.Audit, granted on/pool/lab,/storage/local-lvm,/sdn/zones/localnetworkand/nodes/<node>, never on/. The template (VM ID 9000) and every lab machine sit in the poollab, so the clone rights cover exactly them.ci-plan@pvegets the built-in read-only rolePVEAuditoron the same four paths.- Each user has one API token created with
--privsep 1; such a token has only the rights that are granted to both the token and its user, so every ACL names the user and its token. The token reaches the provider asPROXMOX_VE_API_TOKENfrom the environment’s SOPS file (ADR 0006); the plan token is insecrets/lab-ci.enc.env. - CI reaches the API only through the Access application
lab-pveapiwith a service token (PROXMOX_VE_API_HEADERS); this repository never publishes the API port to the internet. - The setup is a manual procedure on the host (runbook). Each privilege added later is recorded in a new ADR that supersedes this one.
Consequences
- Good: a leaked apply token can create, change and delete machines in the pool
labonly; it cannot change the host, other guests, users or the network configuration. A leaked plan token can read, not write. - Bad: no Proxmox VE host was used for this version, so the privilege list is the plan’s and has
not been proven by an apply; a missing privilege shows up as a
403in the first apply. - Bad: the identities live on the host, not in this repository; rebuilding the host means running the procedure again.
docs/adr/0025-proxmox-ve-api-tokens-with-least-privilege.md on GitHub
Licensed under Apache-2.0. Source: luminare-dev/infra-edge-lab at v0.1.0.