“Permission denied” in the Proxmox Datacenter view is the kind of message that looks like a minor inconvenience—right up until it blocks backups, breaks automation, and turns your on-call shift into interpretive dance with ACL paths.
This isn’t a mystical problem. Proxmox permissions are deterministic. The pain comes from humans: wrong assumptions about ACL inheritance, confusion between Datacenter vs node vs VM paths, and role definitions that grow like mold in a basement.
The permission mental model that actually works
Proxmox permissions are not hard. They’re just layered. If you don’t keep the layers straight, you’ll “fix” access by slapping Administrator on a user at / and call it a day. That works the same way you can fix a leaky faucet by turning off the city’s water supply.
Here’s the model you need:
- Identity: user, group, or API token. Stored in a realm (PAM, PVE, LDAP/AD, OpenID, etc.).
- Role: a named bundle of privileges (for example,
PVEVMAdmin,PVEAuditor). - ACL: binds identity → role on a path, optionally with propagation.
- Path: the resource tree:
/,/dc,/nodes/pve01,/vms/101,/storage/nvme-ssd,/pool/Dev, etc. - Effective privileges: Proxmox computes what you can do at the moment of access, based on all matching ACLs.
“Permission denied in Datacenter” usually means: the user can authenticate, but lacks one or more privileges required to render or operate on something at the /dc scope (or the GUI tried to fetch it at that scope).
Two operational truths:
- Most GUI pages fetch multiple endpoints. You might be allowed to view a VM, but the sidebar wants cluster resources, storage status, or node metrics. One denied call can break a whole view.
- The path is the contract. If the ACL is on
/nodes/pve01but you’re looking at something under/dc(Datacenter), don’t expect miracles.
Joke #1: Giving everyone Administrator at / is like solving ticket queues by unplugging the helpdesk phone. The silence is real, but so is the disaster.
Interesting facts and historical context (the parts that matter)
These aren’t trivia-night facts. They explain why Proxmox permissions look the way they do and why certain failure modes repeat.
- Proxmox’s permission system is strongly influenced by a Unix mindset: identities and groups mapped to a tree of resources. That’s why paths feel “filesystem-ish.”
- The default roles encode operational intent:
PVEVMAdminisn’t “admin,” it’s “admin of VMs,” and it intentionally doesn’t grant everything at Datacenter scope. - Cluster configuration is distributed: in a cluster, permission data is shared via the cluster filesystem. A node that’s partitioned can show stale ACLs and confuse your troubleshooting.
- Historically, UIs in infra products often over-fetch: early “single page app” admin consoles commonly query broad endpoints to populate dashboards. Proxmox GUI behavior inherits some of that pattern.
- Fine-grained storage permissions are a relatively modern expectation: older virtualization stacks assumed “storage admins are hypervisor admins.” In Proxmox, storage objects have explicit ACL paths, which is good—until you forget them.
- API tokens are a response to automation reality: long-lived passwords in scripts are operational debt. Tokens are better, but only if you scope them correctly.
- Least privilege became mainstream because of breaches, not elegance: privilege sprawl isn’t an aesthetic problem; it’s an incident multiplier.
- Proxmox’s RBAC is designed for mixed teams: virtualization admins, storage folks, auditors, and app teams can coexist—if you stop making everything “Administrator.”
- Propagation is a classic foot-gun: inherited permissions are convenient, but they’re also how “temporary access” becomes “forever access.”
How Proxmox evaluates roles and ACLs (and why your GUI lies by omission)
Roles are sets of privileges
A role is a named list of privileges. Privileges are the atomic units like VM.Audit, VM.PowerMgmt, Datastore.Allocate, Sys.Audit, and so on.
Key point: you don’t grant a privilege directly to a user. You grant a role via an ACL. The role is the “package,” the ACL is the “where,” and the user/group/token is the “who.”
ACL paths are a resource tree, not a suggestion
Think in explicit scopes:
/: everything, the root of all paths./dc: datacenter-wide objects (cluster, permissions, pools, storage inventory, etc.)./nodes/<node>: node-specific objects (tasks, services, syslog, local storage on that node)./vms/<vmid>: VM/CT-specific objects./storage/<storageid>: storage object permissions./pool/<poolname>: pool-based access control, useful for delegating groups of VMs.
Datacenter view “permission denied” often happens when you granted the user VM permissions at /vms/101 but not the ability to see certain datacenter objects the GUI queries. You get partial access that looks like broken access.
Propagation controls inheritance down the tree
An ACL can propagate (apply to subpaths) or not. Propagation is powerful. It’s also how you accidentally grant access to every VM when you meant “only that pool.”
Operational advice: propagate only when the path is already narrow (like /pool/Dev), or when it’s truly intentional (like /vms for VM operators). Avoid propagation at / unless you are consciously creating a superuser.
Multiple ACLs combine
Users can be members of groups, and groups can have ACLs. A user can also have direct ACLs. Proxmox computes the union of privileges across all matching ACLs.
This is why “remove user from the admin group” sometimes doesn’t work: they still have a direct ACL somewhere you forgot existed.
The GUI is a client, not a truth oracle
The Proxmox UI is excellent, but it’s still a web client calling the API. When something is denied, it may just show a generic toast message. Your job is to find which API call was denied and which privilege was missing.
When in doubt, treat the GUI as a symptom generator and use CLI to inspect ACLs and roles.
Quote (paraphrased idea): Gene Kranz emphasized that reliability comes from discipline and clear responsibility boundaries, not heroics.
Fast diagnosis playbook
This is the “don’t make it weird” sequence. Do it in order. It will usually tell you the exact missing piece.
First: confirm identity and realm
- Is the user logging in as
user@pvevsuser@pamvsuser@ldap? - Did you grant ACLs to the wrong realm identity (common with AD/LDAP where usernames overlap)?
Second: list the ACLs that apply
- Check direct user ACLs.
- Check group membership and group ACLs.
- Check whether propagation is enabled and whether the ACL path matches the failing area.
Third: inspect the role definition
- Does the role actually include the privilege you think it does?
- Did someone “optimize” a role by removing “unneeded” privileges and break the GUI?
Fourth: reproduce via API and identify the denied endpoint
- Try the same action with
pveshas a privileged user and compare. - Look at task logs and permission-denied messages with context.
Fifth: check cluster consistency if behavior differs by node
- If one node grants access and another denies it, you may have cluster filesystem issues or a partially joined node.
Sixth: only then change ACLs
Don’t thrash. Make one change, test, revert if needed. Permissions changes are production changes.
Practical tasks: commands, outputs, decisions (12+)
All tasks assume you’re running on a Proxmox node as root or an admin user. Commands are real. Outputs are representative. Decisions are what you do next.
Task 1: Confirm the user identity (realm matters)
cr0x@server:~$ pveum user list
USERID ENABLED EXPIRE
root@pam 1
alice@pve 1
alice@ldap 1
svc-terraform@pve 1
What the output means: There are two “alice” users in different realms. ACLs are attached to the full ID including realm.
Decision: Verify which one is logging in. If the complaint is from AD login, you must grant alice@ldap, not alice@pve.
Task 2: List group memberships (hidden privileges live here)
cr0x@server:~$ pveum user get alice@ldap
┌─────────┬───────────────────────────────┐
│ key │ value │
╞═════════╪═══════════════════════════════╡
│ userid │ alice@ldap │
├─────────┼───────────────────────────────┤
│ enable │ 1 │
├─────────┼───────────────────────────────┤
│ groups │ DevOps,VM-Operators │
└─────────┴───────────────────────────────┘
What it means: Alice inherits ACLs from DevOps and VM-Operators.
Decision: Audit those group ACLs before changing anything. The fastest fix is often a missing ACL on a group path, not adding one-off user ACLs.
Task 3: Dump ACLs and search for the user or group
cr0x@server:~$ pveum acl list | egrep -i 'alice@ldap|DevOps|VM-Operators'
/pool/Dev -group VM-Operators -role PVEVMAdmin
/dc -group DevOps -role PVEAuditor
What it means: VM operators have VM admin rights in the Dev pool. DevOps has auditing at datacenter scope.
Decision: If Alice can’t open Datacenter because the GUI needs something beyond PVEAuditor, you either expand the auditor role (carefully) or add a narrow ACL for the missing privilege.
Task 4: Verify role contents (don’t assume)
cr0x@server:~$ pveum role show PVEAuditor
┌──────────────┬──────────────────────────────────────────────┐
│ key │ value │
╞══════════════╪══════════════════════════════════════════════╡
│ roleid │ PVEAuditor │
├──────────────┼──────────────────────────────────────────────┤
│ privileges │ Datastore.Audit Group.Audit Mapping.Audit │
│ │ Permissions.Modify Pool.Audit Realm.Allocate │
│ │ SDN.Audit Sys.Audit VM.Audit │
└──────────────┴──────────────────────────────────────────────┘
What it means: The role is mostly read-only, but note it includes Permissions.Modify in this example (some environments customize this; defaults may differ).
Decision: If your auditor can modify permissions, you’ve built a silent privilege escalation path. Fix the role definition to match intent.
Task 5: Enumerate all privileges and spot what you’re missing
cr0x@server:~$ pveum role list
RoleID Privileges
Administrator *
NoAccess
PVEAdmin Datastore.Allocate Datastore.AllocateSpace ...
PVEAuditor Datastore.Audit Sys.Audit VM.Audit ...
PVEVMAdmin VM.Allocate VM.Audit VM.Config.Disk VM.Config.CPU ...
PVEVMUser VM.Audit VM.Console VM.Monitor VM.PowerMgmt
What it means: Roles are bundles; Administrator is wildcard.
Decision: If you’re tempted to use Administrator, stop. Identify the minimal role needed and apply it on the right path.
Task 6: Check whether the user can list datacenter resources via API (as admin)
cr0x@server:~$ pvesh get /access/users --output-format=json-pretty | head
[
{
"comment": "",
"email": "",
"enable": 1,
"expire": 0,
"firstname": "",
"groups": "DevOps;VM-Operators",
"lastname": "",
"userid": "alice@ldap"
},
...
What it means: As admin, you can retrieve user info. This confirms the API endpoint exists and works.
Decision: If the user can’t load Datacenter, determine which endpoint they’re denied. Use browser dev tools or replicate likely calls (next tasks).
Task 7: Quickly test if the issue is “can’t see nodes”
cr0x@server:~$ pvesh get /nodes
[
{
"cpu": 0.03,
"maxcpu": 16,
"maxmem": 68719476736,
"mem": 12461883392,
"node": "pve01",
"status": "online",
"uptime": 223948
},
{
"cpu": 0.05,
"maxcpu": 16,
"maxmem": 68719476736,
"mem": 18372743168,
"node": "pve02",
"status": "online",
"uptime": 221402
}
]
What it means: Nodes exist and are accessible for an admin. A non-admin user might get denied if they lack Sys.Audit or equivalent privileges at /nodes or /.
Decision: If Datacenter sidebar fails, ensure the user has at least audit-level rights on /nodes or /dc depending on what you want them to see.
Task 8: Inspect storage inventory; missing storage ACLs cause surprise denials
cr0x@server:~$ pvesh get /storage
[
{
"content": "images,rootdir,iso,vztmpl,backup",
"enabled": 1,
"shared": 1,
"storage": "ceph-hdd"
},
{
"content": "images,rootdir,backup",
"enabled": 1,
"shared": 0,
"storage": "local-lvm"
}
]
What it means: Storage objects exist; GUI panels frequently query them.
Decision: If a user can manage VMs but can’t attach disks or browse ISO/backup storage, add ACLs on /storage/<id> with a role that includes the needed datastore privileges.
Task 9: Show current ACLs in a readable way (full dump)
cr0x@server:~$ pveum acl list
/dc -group DevOps -role PVEAuditor
/pool/Dev -group VM-Operators -role PVEVMAdmin
/storage/ceph-hdd -group VM-Operators -role PVEDatastoreUser
What it means: Permissions are sparse and clear. Good sign.
Decision: If the user complains about Datacenter view denial, check whether /dc role includes enough read privileges for the UI sections they need.
Task 10: Add a narrowly scoped ACL (example: allow monitoring only)
cr0x@server:~$ pveum acl modify /nodes -group VM-Operators -role PVEAuditor
cr0x@server:~$ pveum acl list | grep '/nodes'
/nodes -group VM-Operators -role PVEAuditor
What it means: VM operators can audit node status without being node admins.
Decision: If this fixes Datacenter visibility, keep it. If it exposes more than desired, narrow it to /nodes/pve01 or remove and instead grant only /dc audit rights plus specific endpoints (harder to manage).
Task 11: Validate pool usage; pool ACLs are the cleanest delegation mechanism
cr0x@server:~$ pvesh get /pools
[
{
"poolid": "Dev"
},
{
"poolid": "Prod"
}
]
What it means: Pools exist.
Decision: Put tenant/team VMs into pools and assign roles at /pool/<pool> with propagation. This beats per-VM ACLs for sanity.
Task 12: Confirm a VM is in the expected pool (or not)
cr0x@server:~$ pvesh get /pools/Dev --output-format=json-pretty | head -n 30
{
"members": [
{
"id": "qemu/101",
"node": "pve01",
"type": "qemu",
"vmid": 101
},
{
"id": "lxc/120",
"node": "pve02",
"type": "lxc",
"vmid": 120
}
],
"poolid": "Dev"
}
What it means: VM 101 is in Dev pool, so /pool/Dev ACLs apply.
Decision: If a user can’t manage “their” VM, first check if the VM is in the correct pool before editing ACLs.
Task 13: Detect role drift (custom roles are where good intentions go to die)
cr0x@server:~$ pveum role show VMOperatorCustom
roleid: VMOperatorCustom
privileges: VM.Audit VM.Console VM.PowerMgmt VM.Snapshot
What it means: Custom role is missing VM.Config.Disk and Datastore.AllocateSpace, so disk operations may fail.
Decision: Decide whether VM operators should manage disks. If yes, update the role; if no, document that limitation and provide a request path for storage changes.
Task 14: Audit API tokens (they often outlive the humans who created them)
cr0x@server:~$ pveum user token list svc-terraform@pve
tokenid expire privsep
tf-ci 0 1
tf-prod 0 1
What it means: Tokens exist and use privilege separation (privsep=1), which is good. It means token permissions are separate from the user’s permissions.
Decision: Ensure each token has explicit ACLs on the minimal paths it needs. Don’t rely on broad user permissions.
Task 15: Check cluster health when permissions seem inconsistent across nodes
cr0x@server:~$ pvecm status
Cluster information
-------------------
Name: corp-pve
Config Version: 27
Transport: knet
Secure auth: on
Quorum information
------------------
Date: Fri Dec 26 12:40:11 2025
Quorum provider: corosync_votequorum
Nodes: 3
Node ID: 0x00000001
Ring ID: 1.2a
Quorate: Yes
What it means: Cluster is quorate; config (including permissions) should be consistent.
Decision: If you are quorate and still see mismatched behavior, suspect caching in the browser, different realm auth paths, or node-local issues like time skew affecting tokens.
Role design: what to create, what to ban, and what to keep boring
RBAC design is where Proxmox shops either become clean or become haunted. The goal is not perfection. The goal is: predictable permissions you can explain at 03:00.
Principle 1: Prefer group ACLs over user ACLs
User ACLs scale like a rumor: fast, messy, and hard to retract. Use groups for humans. Use tokens for automation. Use direct user ACLs only for break-glass or temporary access with an expiry date you actually honor.
Principle 2: Use pools for delegation
If you’re not using pools, you’re doing ACLs the hard way. Pools give you a stable handle for “team owns these VMs/CTs.” Grant roles at /pool/TeamX with propagation. Move workloads between pools as ownership changes. That’s the clean seam.
Principle 3: Separate “can operate VMs” from “can mutate infrastructure”
VM operators should be able to:
- Start/stop/reboot
- Console access
- View configuration and metrics
- Snapshot (maybe)
They usually should not be able to:
- Add new storage backends
- Edit cluster networking
- Modify permissions
- Manage nodes/services
This sounds obvious until you realize how often people grant node-level privileges just to stop a UI error.
Principle 4: Create a small number of custom roles, and treat them like code
Default roles exist for a reason. Custom roles are fine, but each custom role should have:
- a one-sentence purpose (“VM operator with disk attach rights in Dev only”)
- a clearly defined scope path where it is allowed
- an owner (team) responsible for reviewing it quarterly
Principle 5: Don’t “fix” permission denied by widening the scope
If the user gets denied at Datacenter, the fix is rarely “Administrator at /dc.” It’s usually one of:
- wrong realm identity
- ACL on wrong path
- role missing one privilege required by UI
- pool membership wrong
- storage ACL missing
Joke #2: The fastest way to resolve an RBAC ticket is to delete RBAC. Security teams call this “career development.”
Three corporate mini-stories from the trenches
Mini-story 1: The incident caused by a wrong assumption
They had a tidy Proxmox cluster for internal services: CI runners, build caches, a few “temporary” app environments that became permanent because nobody likes redoing work. A platform engineer created a “VM Admin” group and applied PVEVMAdmin at /vms, assuming that would be enough for day-to-day operations.
Then a developer filed a ticket: “Datacenter view is broken, permissions denied.” The engineer opened the GUI as the developer and saw the error banner. The immediate assumption was that the role was wrong, so they escalated: they added PVEAdmin at /dc to the group. Error gone. Ticket closed. Everyone happy.
A week later, backups started failing—not because they couldn’t run, but because someone “helpfully” edited the backup storage configuration while debugging a different issue. They had access because PVEAdmin at /dc includes broad datacenter privileges. The resulting configuration was valid enough to save, wrong enough to break restores. The failure only surfaced during a recovery test.
The root cause wasn’t malice. It was the wrong assumption: that Datacenter view requires datacenter admin privileges. In reality, it needed audit visibility to nodes and storage for the GUI panels they were loading. The correct fix would have been narrow: grant PVEAuditor at /nodes and a datastore-user role on specific storage paths, or tune a custom role with only the audit privileges required.
The remediation was boring: remove the broad ACL, add precise ones, and document “GUI errors are API endpoint errors, not role failures.” It reduced their blast radius immediately.
Mini-story 2: The optimization that backfired
A large enterprise team decided they had “too many roles.” They were trying to standardize access across virtualization, Kubernetes, and bare metal. Someone proposed a simplification: create a single custom Proxmox role called OpsStandard that would cover 95% of needs. They pulled privileges from several existing roles and removed anything that “looked risky.”
At first it worked. Fewer role names, fewer ACL lines. Then the weirdness began: VM migrations failing for some users, snapshot operations intermittently denied, and the UI sometimes showing empty storage lists. Each symptom showed up in different corners of the product, which made it feel like a Proxmox bug.
The real problem was the “optimization.” They removed a handful of privileges that seemed tangential, but which the GUI and workflows relied on. The role still allowed powering on VMs, so people assumed it was fine. It wasn’t. The denied privileges were required for ancillary queries and state updates.
They ended up with a role that was simultaneously too broad (it applied at / to avoid edge cases) and too narrow (missing key privileges). That’s a special kind of broken: it creates toil without actually enforcing least privilege.
Fixing it meant undoing the simplification. They went back to a small set of roles aligned to responsibilities, and they limited scope using pools and storage paths rather than “one role to rule them all.” The final design had more lines in ACLs, but fewer incidents.
Mini-story 3: The boring but correct practice that saved the day
A finance-adjacent team ran Proxmox for a set of compliance-sensitive workloads. They had a habit that everyone mocked: quarterly access reviews. Not a spreadsheet theater exercise—an actual review of groups, roles, and ACL paths, with a second person verifying.
During one review they noticed something subtle: an old contractor account was disabled, but its API token still existed. The token had its own ACLs because privilege separation was enabled. It also had access to /storage/backup-nfs with a role that allowed reading backups.
Nothing bad had happened yet. That’s the point. They revoked the token, removed the ACL, and rotated a few secrets. Later that year, a different system was compromised and attackers probed internal APIs. The Proxmox token would have been an easy path to stealing backups if it still existed.
What saved them wasn’t a clever tool. It was the boring practice: treat tokens as production credentials, review them, and delete them when the owning service or person is gone.
They also kept their RBAC design painfully simple: pools for ownership, separate groups for auditing vs operating, and no custom roles unless there was a written requirement. As a result, when they did see “permission denied” errors, diagnosis was fast because the system was legible.
Common mistakes: symptom → root cause → fix
1) Symptom: “Permission denied” when clicking Datacenter, but VM console works
Root cause: User has VM-level privileges (/vms/<id> or /pool/<pool>) but lacks audit rights for nodes/storage queried by the Datacenter UI.
Fix: Add an audit role on /nodes (or /dc if appropriate) and datastore audit/user role on required /storage/<id>. Keep it read-only unless you intend more.
2) Symptom: Works for alice@pve but not for alice@ldap
Root cause: ACLs granted to the wrong realm identity.
Fix: Grant ACLs to the correct user@realm. Consider disabling local shadow accounts to reduce confusion.
3) Symptom: User can start/stop VMs but cannot attach ISO images
Root cause: Missing datastore privileges on the ISO storage path (/storage/<id>), not a VM privilege issue.
Fix: Add a datastore user/auditor role on that storage, or move ISOs to a storage with appropriate ACLs.
4) Symptom: Backup job fails with permission errors only when run by automation
Root cause: API token has privilege separation enabled and doesn’t inherit the user’s ACLs; token lacks its own ACLs.
Fix: Add ACLs for the token identity at required paths, or disable privilege separation only if you accept the coupling (usually you shouldn’t).
5) Symptom: Datacenter → Permissions page is inaccessible to “auditors”
Root cause: Auditor role missing relevant audit privileges for permissions objects, or you intentionally restricted it and the GUI is correctly denying.
Fix: Decide intent. If they must view permissions, add the necessary audit privilege via role update. If not, stop promising access to that page.
6) Symptom: User sees some VMs but not others in the same team
Root cause: VMs not consistently assigned to the pool, or per-VM ACLs diverged over time.
Fix: Normalize using pools. Move VMs into the correct pool; remove per-VM ACLs unless there’s a documented exception.
7) Symptom: Permissions appear correct, but user still gets denied after changes
Root cause: Browser cached session/token; user is logged in under a different realm; or you changed group membership but the session hasn’t refreshed.
Fix: Have user log out/in; confirm realm in the top-right user label; re-check using CLI and ensure you modified the correct identity.
8) Symptom: Different nodes behave differently for the same user
Root cause: Cluster inconsistency (quorum issues, node not fully joined) or node-local auth integration differences.
Fix: Check pvecm status, ensure quorate; verify realm config on all nodes; fix cluster filesystem health before touching ACLs.
Checklists / step-by-step plan
Checklist A: Build RBAC correctly for a team (human users)
- Create (or use) an auth realm that matches corporate identity (LDAP/AD/OIDC). Don’t create duplicate local users unless you mean to.
- Create groups that map to responsibilities, not org charts:
VM-Operators,VM-Auditors,Storage-Operators. - Create pools per team or environment:
Dev,Prod,Analytics. - Put VMs/CTs into pools as the source of truth for ownership.
- Grant roles on
/pool/<pool>with propagation:PVEVMUserorPVEVMAdmindepending on whether they can change config.
- Grant
PVEAuditoron/nodesif they need to see node status in the GUI. - Grant datastore roles on specific
/storage/<id>paths for ISO/backup access if required. - Document what they cannot do (snapshots? disk resize? migrations?). Fewer surprises = fewer “just make it admin” requests.
Checklist B: Fix a live “Datacenter permission denied” ticket without making it worse
- Confirm the user’s realm and exact user ID (
user@realm). - List the user’s groups and existing ACLs.
- Identify the page/action that fails. Ask for the exact click path and time.
- Check whether the user can:
- list nodes (audit)
- list storage (audit)
- see the pool and its members
- If missing, add the minimal audit ACLs on the correct path.
- Re-test with the user. If fixed, stop. Don’t “improve” it further on the fly.
- If not fixed, identify the denied endpoint by inspecting task logs or reproducing with API calls.
- Only as a last resort, temporarily grant a broader role with a time limit and a rollback plan.
Checklist C: Token-based automation done safely
- Create a dedicated service user per automation domain (e.g.,
svc-terraform@pve). - Create tokens per environment (
tf-dev,tf-prod) so you can revoke surgically. - Keep
privsep=1and assign explicit token ACLs. Don’t piggyback on user ACLs. - Grant access at pool scope and required storage scope, not at
/. - Review tokens quarterly and delete unused ones. Rotate credentials when staff changes or pipelines change ownership.
FAQ (8+)
1) Why does Proxmox show “permission denied” in Datacenter when I only want VM access?
Because the GUI loads datacenter-wide and node-wide data to populate the sidebar, dashboards, and status panels. VM-only ACLs don’t necessarily cover those API calls.
2) Should I just grant PVEAuditor at / so everyone can see everything?
No. Grant audit rights at /nodes and /dc only if needed, and consider what “see everything” means in your org. Visibility is still access.
3) What’s the safest way to give a team access to “their” VMs?
Use pools. Put their VMs/CTs in /pool/Team and assign a VM-focused role there with propagation. It’s clean and reversible.
4) Why can’t my VM operator attach disks or mount ISOs?
Disk/ISO operations often touch storage objects. You need appropriate privileges on /storage/<id> in addition to VM privileges.
5) Do API tokens inherit the user’s permissions?
Not if privilege separation is enabled for the token (privsep=1). In that case, tokens need their own ACLs. This is usually what you want for automation.
6) I granted the right role, but it still says denied. What now?
Confirm you granted it to the correct identity (user@realm), on the correct path, with propagation if needed. Then have the user log out/in to refresh the session.
7) Is it okay to customize default roles?
You can, but treat it like modifying a production library: version it mentally, document it, and expect surprises. Prefer creating a new custom role so defaults remain predictable.
8) How do I stop privilege sprawl over time?
Use group-based ACLs, pool-based scoping, and quarterly reviews of ACLs and tokens. Delete one-off user ACLs unless there’s a written exception.
9) Why does it work on one node and not another?
Either you’re not actually in a consistent cluster state (quorum/config distribution), or auth realm configuration differs per node, or the user is authenticating differently. Fix consistency first.
10) What’s the “right” place to assign permissions: /dc or /?
Almost never /. Use /dc for datacenter-wide read needs (and only for trusted admin roles for write). Use pools, nodes, and storage paths for everything else.
Conclusion: next steps you can do today
Proxmox “permission denied” errors in Datacenter aren’t random. They’re the system telling you your RBAC story doesn’t match how the GUI and API actually access resources.
Do these next steps:
- Pick one troubled user and map their identity → groups → ACL paths → roles. Write it down in four lines. If you can’t, your RBAC is already too clever.
- Move team workloads into pools and stop doing per-VM ACL whack-a-mole.
- Add minimal audit access for nodes/storage only when needed for visibility. Don’t use “Datacenter access” as an excuse for datacenter admin.
- Inventory API tokens, confirm
privsep=1, and ensure each token has explicit, narrow ACLs. - Schedule a quarterly RBAC review. Yes, it’s boring. That’s why it works.