Proxmox API Token Security: Creation, Permissions, and Rotation
How to create and manage API tokens in Proxmox VE with proper privilege separation, scoped permissions, rotation strategies, and audit logging.
Why Use API Tokens?
API tokens in Proxmox VE provide a way to authenticate to the API without using your user password. They are essential for automation scripts, CI/CD pipelines, monitoring tools, and third-party integrations. Unlike password-based authentication (which uses short-lived tickets), API tokens are long-lived credentials that can be individually scoped, rotated, and revoked without affecting the parent user account.
Create an API Token
Use the pveum command to create tokens from the command line:
# Create a token for user root@pam:
pveum user token add root@pam automation-token
# Output will include the token secret (save it immediately!):
# Token: root@pam!automation-token
# Secret: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
# The secret is shown only once. Store it securely.
# Create a token for a specific user:
pveum user token add deploy@pve deploy-token
# List tokens for a user:
pveum user token list root@pam
You can also create tokens from the web UI: Datacenter > Permissions > API Tokens > Add.
Privilege Separation: On vs Off
When creating a token, Proxmox offers a critical option: privilege separation.
# Token WITH privilege separation (default, recommended):
pveum user token add deploy@pve ci-token --privsep 1
# This token has NO permissions by default.
# You must explicitly grant permissions to the token.
# Token WITHOUT privilege separation:
pveum user token add deploy@pve ci-token --privsep 0
# This token inherits ALL permissions of the parent user.
# Less secure but simpler for testing.
Always use privilege separation in production. A token without privilege separation that gets leaked gives the attacker the same access as the parent user. With privilege separation, you can limit the token to only the specific operations it needs.
Assign Scoped Permissions
With privilege separation enabled, grant the token only the permissions it needs:
# Give the token read-only access to all VMs:
pveum aclmod /vms -token 'deploy@pve!ci-token' -role PVEAuditor
# Give the token power management for a specific VM (ID 100):
pveum aclmod /vms/100 -token 'deploy@pve!ci-token' -role PVEVMUser
# Give the token full admin on a specific storage:
pveum aclmod /storage/local-lvm -token 'deploy@pve!ci-token' -role PVEDatastoreAdmin
# Create a custom role with specific privileges:
pveum roleadd DeployRole -privs "VM.Allocate VM.Clone VM.Config.Disk VM.PowerMgmt Datastore.AllocateSpace"
pveum aclmod /vms -token 'deploy@pve!ci-token' -role DeployRole
# View current token permissions:
pveum acl list | grep ci-token
Use API Tokens in Scripts
Authenticate with API tokens in your automation scripts:
# Using curl:
curl -s -k \
-H "Authorization: PVEAPIToken=deploy@pve!ci-token=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \
https://proxmox-host:8006/api2/json/nodes
# Using Python with proxmoxer:
from proxmoxer import ProxmoxAPI
prox = ProxmoxAPI(
'proxmox-host',
user='deploy@pve',
token_name='ci-token',
token_value='xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
verify_ssl=False
)
nodes = prox.nodes.get()
# Using Terraform:
# provider "proxmox" {
# pm_api_url = "https://proxmox-host:8006/api2/json"
# pm_api_token_id = "deploy@pve!ci-token"
# pm_api_token_secret = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# }
Token Rotation Strategy
API tokens do not expire by default in Proxmox. Implement a rotation strategy to limit the impact of a compromised token:
# Set an expiration date on a token:
pveum user token add deploy@pve quarterly-token --expire 1743465600
# Timestamp is Unix epoch (use: date -d "2025-04-01" +%s)
# Rotation process:
# 1. Create a new token with the same permissions:
pveum user token add deploy@pve ci-token-v2 --privsep 1
pveum aclmod /vms -token 'deploy@pve!ci-token-v2' -role DeployRole
# 2. Update your scripts/tools with the new token
# 3. Revoke the old token:
pveum user token remove deploy@pve ci-token
# Automate rotation reminders with a cron job:
# 0 9 1 */3 * echo "API token rotation due" | mail -s "Proxmox Token Rotation" admin@example.com
Revoke Tokens
When a token is compromised or no longer needed, revoke it immediately:
# Remove a specific token:
pveum user token remove deploy@pve ci-token
# List all tokens for a user to audit:
pveum user token list deploy@pve
# Remove all tokens for a user:
for token in $(pveum user token list deploy@pve --output-format json | jq -r '.[].tokenid'); do
pveum user token remove deploy@pve "$token"
done
Audit Trail
Proxmox logs all API access, including token-authenticated requests. Monitor the audit log to detect suspicious activity:
# View recent API activity:
tail -100 /var/log/pveproxy/access.log
# Filter for a specific token:
grep "ci-token" /var/log/pveproxy/access.log
# Check authentication failures:
journalctl -u pvedaemon | grep "authentication failure"
# Monitor real-time API access:
tail -f /var/log/pveproxy/access.log
Managing API tokens is especially important if you use tools like Terraform, Ansible, or monitoring systems that connect to your Proxmox cluster. ProxmoxR uses API tokens for secure authentication, giving you a practical example of how token-based access works for mobile management of your Proxmox infrastructure.
Summary
API tokens in Proxmox VE are the correct way to authenticate automation tools and third-party integrations. Always enable privilege separation and assign the minimum permissions needed. Implement a rotation strategy since tokens do not expire by default, revoke tokens immediately when compromised, and monitor the audit log for unusual access patterns. Proper token management is a critical part of your Proxmox security posture.
Take Proxmox management mobile
All the features discussed in this guide — accessible from your phone with ProxmoxR. Real-time monitoring, power control, firewall management, and more.