Every homelab running Proxmox eventually hits the automation wall. You want Terraform to spin up VMs, Ansible to configure LXC containers, or a monitoring tool to query node status. The default approach — embedding the root password into scripts and CI pipelines — works until it doesn’t. One leaked env file, one committed secret in a public repo, and your entire virtualization host is exposed.

Proxmox API tokens solve this cleanly. Combined with role-based access control (RBAC), you grant each automation tool exactly the permissions it needs, scoped to specific resources, without ever sharing a password. This guide walks through token creation, role assignment, and practical integration with Terraform and Ansible.

Understanding Proxmox Authentication and RBAC

Proxmox supports three authentication realms: PAM (system users), PVE (Proxmox-built-in user database), and external realms like LDAP or OIDC. API tokens work with any realm but are most commonly created from PVE users for service accounts.

RBAC in Proxmox has three components: users, roles (collections of privileges), and paths (resource hierarchy). Permissions flow down the path tree. A role assigned to /vms applies to every VM under it. Roles assigned to a specific VM path like /vms/100 override parent permissions for that single resource.

The built-in roles cover most use cases:

  • Administrator — full access to everything
  • PVEAuditor — read-only view of all resources
  • PVEAdmin — full access except user/token/pool management
  • PVEDatastoreUser — storage management and template operations
  • PVEVMUser — manage VMs and containers without storage or template rights
  • PVETemplateUser — create and deploy templates
  • PVEPoolUser — manage resource pools

For automation, you rarely need anything beyond PVEVMUser or PVEAuditor. Start restrictive and expand as needed.

Creating Users and API Tokens

Create a dedicated service user for automation. Never use your personal admin account.

1
2
3
# Create a PVE-authentication service user
pveum user add automation@pve --comment "Automation service account"
pveum passwd automation@pve

The password is required for user creation but you won’t use it for API access — the API token authenticates independently. Now generate an API token bound to that user:

1
pveum user token add automation@pve terraform --privsep=0

The output includes:

  • Token ID: automation@pve!terraform
  • Secret: a UUID string that serves as the bearer token

The --privsep=0 flag disables privilege separation, meaning the token inherits the user’s full permissions. With --privsep=1, the token starts with zero privileges and you must grant permissions to the token itself rather than inheriting from the user. For most automation scenarios, privsep=0 is simpler and safe when combined with restrictive role assignments.

View your existing tokens at any time:

1
pveum user token list automation@pve

Important: The secret is shown only once at creation time. Store it in a password manager or vault immediately. Proxmox hashes the token secret and cannot recover it later — you would need to delete and recreate the token.

Assigning Roles and Permission Paths

A token with no role assignments is useless. Assign roles on specific resource paths to control what the token can do.

1
2
3
4
5
6
7
8
# Grant VM management on all VMs
pveum acl modify /vms --user automation@pve --role PVEVMUser

# Grant storage access to a specific datastore
pveum acl modify /storage/local --user automation@pve --role PVEDatastoreUser

# Grant audit (read-only) access to the node itself
pveum acl modify /nodes/srv1 --user automation@pve --role PVEAuditor

The resource hierarchy uses these path prefixes:

Path Scope
/ Entire datacenter
/vms All VMs and containers
/vms/100 Single VM or container 100
/nodes/srv1 Specific node resources
/storage/local Specific storage
/pool/production Resource pool named “production”

For fine-grained control, grant the minimal role at the most specific path. A Terraform token that only provisions VMs in a production pool needs nothing beyond /pool/production with PVEVMUser.

You can also create deny rules by omitting privileges or using a restrictive custom role (covered below).

Authenticating with API Tokens from Automation Tools

API tokens authenticate via HTTP header. Every Proxmox API call includes the token ID and secret.

Direct API Access

Test your token with a simple curl call:

1
2
curl -s -H "Authorization: PVEAPIToken=automation@pve!terraform=uuid-secret" \
  https://proxmox:8006/api2/json/nodes

The token format is always USER@REALM!TOKENID=SECRET. Replace uuid-secret with your actual token secret.

Terraform Integration

The Proxmox Terraform provider (bpg/proxmox) supports token authentication natively:

1
2
3
4
5
6
provider "proxmox" {
  endpoint  = "https://10.0.20.30:8006/"
  api_token = "automation@pve!terraform=uuid-secret"
  # Enable TLS verification in production
  insecure  = false
}

For CI/CD pipelines, inject the token via environment variable to avoid hardcoding:

1
export PM_API_TOKEN="automation@pve!terraform=uuid-secret"

Ansible Integration

The community.general.proxmox modules support token-based auth:

1
2
3
4
5
# group_vars/proxmox.yml
proxmox_api_host: 10.0.20.30
proxmox_api_user: automation@pve!terraform
proxmox_api_token_id: automation@pve!terraform
proxmox_api_token_secret: "{{ vault_proxmox_token }}"

Store the secret in Ansible Vault or your secrets manager, never in plain-text variables.

Token Security Best Practices

API tokens eliminate password sharing but introduce their own security surface. Follow these practices to keep your Proxmox host secure:

Use one token per tool. If Terraform gets compromised, you revoke one token instead of rebuilding every pipeline. Name tokens descriptively so you know which tool uses which:

1
2
3
pveum user token add automation@pve terraform
pveum user token add automation@pve ansible
pveum user token add automation@pve monitoring

Rotate tokens regularly. Delete and recreate tokens on a schedule or after any security incident:

1
2
pveum user token delete automation@pve terraform
pveum user token add automation@pve terraform

Audit token usage. Proxmox logs all API access through pveproxy. Check who accessed what:

1
grep "automation@pve" /var/log/pveproxy/access.log | tail -50

Never commit tokens to Git. Use environment variables, HashiCorp Vault, Ansible Vault, or a secrets manager. If a token is exposed, revoke it immediately.

Use short-lived tokens for CI/CD. If your CI platform supports it, generate fresh tokens per pipeline run and revoke them on completion.

Custom Role Creation for Fine-Grained Access

When built-in roles are too broad or too narrow, create custom roles with exactly the privileges you need.

1
2
3
4
5
6
7
8
# Read-only VM access with console and CD-ROM mount
pveum role add CustomVMViewer -privs "VM.Audit VM.Console VM.Config.CDROM"

# Backup-only role — can create snapshots but not modify VMs
pveum role add CustomBackupOperator -privs "VM.Audit VM.Backup VM.Snapshot"

# Monitoring role — node and storage stats only
pveum role add CustomMonitor -privs "Sys.Audit Sys.Syslog Datastore.Audit Pool.Audit"

The privilege system is granular. Common privileges for automation roles include:

Privilege What it grants
VM.Audit List and view VM configuration
VM.PowerMgmt Start, stop, reset VMs
VM.Config.CDROM Mount ISO images
VM.Config.Disk Add or resize disks
VM.Backup Create and restore backups
VM.Snapshot Create and manage snapshots
VM.Clone Clone VMs and templates
Datastore.Audit List storage contents
Datastore.Allocate Upload files and templates
Sys.Audit Read-only node access
Sys.Syslog Access system logs

Assign your custom role to specific paths:

1
pveum acl modify /vms/200 --user automation@pve --role CustomVMViewer

This grants VM200 read access and console capability, but nothing else — even on the same node.

Testing and Troubleshooting

After setting up roles and tokens, verify the permissions are correct:

1
2
curl -s -H "Authorization: PVEAPIToken=automation@pve!terraform=uuid-secret" \
  https://proxmox:8006/api2/json/access/permissions | jq .

This returns the effective permissions for the token. If a privilege is missing, it won’t appear in the response.

Common issues:

  • 401 Unauthorized — token secret is wrong or token was deleted. Create a new token.
  • 403 Forbidden — token authenticated but lacks permissions on the requested path. Check ACL assignments with pveum acl list.
  • 500 path not found — the resource path in the ACL doesn’t match any actual resource. Verify resource IDs and paths.

Debug token information:

1
pveum user token info automation@pve terraform

This shows the token’s creation date, expiration, and privilege separation mode.

Conclusion

API tokens with RBAC transform Proxmox from a manual management tool into an automation-ready platform. Each token acts as an independent credential — revocable, scoped, and auditable — without the risk of sharing root passwords across scripts and CI pipelines.

Start with the principle of least privilege: create one user, one token per automation tool, assign the narrowest role on the most specific path, and audit regularly. Your homelab automation will be more secure, easier to troubleshoot, and simpler to maintain.

From there, integrate with Terraform for infrastructure-as-code VM provisioning, Ansible for post-deployment configuration, or custom scripts for backup automation — all authenticated through tokens instead of passwords.