Housemate Lab Access¶
Procedure for onboarding a housemate user to a Proxmox sandbox: dedicated resource pool, ZFS-quota-bounded storage, scoped RBAC. Trusted-LAN scope — VMs land on vmbr0/VLAN 1 today; future L2 isolation captured in Phase 8. PBS UI access for the housemate is deliberately out of scope at this stage (operator handles restore); see step 6 for the future-enhancement path.
Prerequisites¶
- Proxmox host healthy (
pvecm statusclean, sufficient ZFS free onstash)
Variables used in this runbook¶
| Variable | Value |
|---|---|
| Username (PVE) | hazel@pve |
| Group | housemate-lab-admins |
| Pool | housemate-lab |
| ZFS dataset | stash/housemate-vms (quota 500 GiB) |
| PVE storage | housemate-zfs |
Step 1 — Create the storage substrate¶
# Carve the ZFS dataset with a hard quota
zfs create -o quota=500G stash/housemate-vms
# Verify
zfs get quota stash/housemate-vms
# Add as PVE storage, ZFS plugin, content limited to VM disks + LXC roots
pvesm add zfspool housemate-zfs \
--pool stash/housemate-vms \
--content images,rootdir \
--sparse 1
Why a ZFS quota and not a Proxmox storage limit
Proxmox storage doesn't enforce per-storage size caps. The ZFS dataset quota is the hard cap; PVE just sees "available" space and respects what the FS reports.
Step 2 — Create the pool¶
Step 3 — Create the user and group¶
# Group first
pveum group add housemate-lab-admins --comment "Housemate Proxmox sandbox"
# User in the PVE realm (not pam — no host shell account)
pveum user add hazel@pve --groups housemate-lab-admins --comment "Hazel — housemate lab"
# Set initial password (interactive prompt)
pveum passwd hazel@pve
Realm choice
Always @pve, never @pam. PAM users are real Linux accounts on the host with shell access; PVE-realm users exist only inside Proxmox auth.
Step 4 — TOTP enforcement¶
In the PVE UI, log in as Hazel for the first time and set up TOTP under Datacenter → Permissions → Two Factor. Easier to walk through together than via API.
Step 5 — Apply the ACL set¶
Three permissions, all on the group:
# VM lifecycle within the pool
pveum acl modify /pool/housemate-lab \
--groups housemate-lab-admins --roles PVEVMAdmin
# Storage write — only this storage, not local-zfs or stash root
pveum acl modify /storage/housemate-zfs \
--groups housemate-lab-admins --roles PVEDatastoreUser
# Network attach to vmbr0 — required for VM creation per
# /usr/share/perl5/PVE/API2/Qemu.pm:1138
pveum acl modify /sdn/zones/localnetwork/vmbr0 \
--groups housemate-lab-admins --roles PVESDNUser
PVESDNUser is required even with no SDN configured
PVE 9 routes all bridge-attach permission checks through the SDN tree, even for plain non-SDN bridges like vmbr0. The implicit ACL path is /sdn/zones/localnetwork/<bridge>. Without SDN.Use here, PVEVMAdmin on the pool is not enough to create a VM — the network step fails with a permission error.
Step 6 — PBS coverage¶
The existing pbs-daily job (02:00 daily, all VMs to nas-primary, root namespace) picks up Hazel's pool VMs automatically once they land — no PBS-side change needed. Hazel does not get a PBS user or UI access at this stage; restore is operator-mediated.
Future enhancement — self-service PBS UI for the housemate
If Hazel later needs to browse her own backups, you'd:
PVE side — edit pbs-daily (or add a new pool-scoped backup job) so VMs in pool housemate-lab write to --namespace housemate. The namespace auto-creates on first backup write; there is no explicit proxmox-backup-manager namespace create subcommand in PBS 4.x.
PBS side (on CT 105):
proxmox-backup-manager user create hazel@pbs --comment "Housemate lab"
proxmox-backup-manager acl update /datastore/nas-primary/housemate \
DatastoreBackup --auth-id hazel@pbs
proxmox-backup-manager acl update /datastore/nas-primary/housemate \
DatastoreAudit --auth-id hazel@pbs
Verified syntax for acl update is <path> <role> --auth-id <id> (path and role are positional; auth ID is a flag). The earlier draft of this runbook had the args inverted — corrected 2026-05-01.
PBS 4.x ACL footgun: attach ACLs to hazel@pbs (the user), never to hazel@pbs!some-token. Token ACLs silently resolve to zero perms; tokens inherit from their parent user.
Step 7 — Guidelines for Hazel¶
Provide a written copy:
- Per-VM caps: 4 vCPU / 8 GiB RAM / 200 GiB disk. Pool quota is 500 GiB total across all VMs.
- Snapshot before risky changes.
qm snapshot <vmid> <name>or via UI. - Don't pass through host devices. You won't have permission anyway, but ping me first if you think you need it.
- Backups are automatic. Daily 02:00 to PBS. You don't have direct access to PBS — if you ever need to restore a VM or pull files out of a backup, ping me.
- Federation / public exposure is a separate conversation. Lab VMs are LAN-only by default — no port forwards, no DNS records, no reverse-proxy entries unless we explicitly set them up together.
- Performance issues affecting the host (Plex stuttering, etc.) — ping me, we'll figure out which side it's coming from.
Verification — try it as Hazel¶
Log in as hazel@pve and verify:
- Login works; TOTP prompt appears
- Datacenter view shows only the
housemate-labpool (no other VMs/storages visible) - Create a tiny test VM (1 vCPU / 1 GiB / 16 GiB) on
housemate-zfs, attached tovmbr0 - Test VM boots, gets DHCP from UDM (192.168.1.x), reaches the internet
- Snapshot the test VM, restore from snapshot
- (Operator) Confirm test VM appears in PBS the morning after creation under root namespace
- Destroy the test VM, verify ZFS dataset reclaim
Removal¶
To revoke access cleanly:
# Stop and delete all VMs in the pool first (Hazel can do this; or as root)
# Then:
pveum acl delete /pool/housemate-lab \
--groups housemate-lab-admins --roles PVEVMAdmin
pveum acl delete /storage/housemate-zfs \
--groups housemate-lab-admins --roles PVEDatastoreUser
pveum acl delete /sdn/zones/localnetwork/vmbr0 \
--groups housemate-lab-admins --roles PVESDNUser
pveum user delete hazel@pve
pveum group delete housemate-lab-admins
pvesm remove housemate-zfs
zfs destroy -r stash/housemate-vms
PBS-side cleanup only applies if the future-enhancement block in step 6 was activated — otherwise nothing to remove.
Future migration to the Lab VLAN
When Phase 8 lands, step 8G replaces the /sdn/zones/localnetwork/vmbr0 ACL with one on the Lab VNet, and Hazel's VMs migrate from vmbr0 to the new VLAN-aware bridge.
Lessons from the 2026-05-01 run¶
Steps 1-5 landed on proxfold cleanly:
- ZFS dataset + PVE storage created (
housemate-zfs, 500 GiB quota) - Pool, group, user (no password yet) created
- All three ACLs verified via
pveum user permissions hazel@pve— pool/storage/SDN paths exactly as scoped, no spurious privileges
Step 6 was descoped mid-execution — Hazel doesn't need self-service PBS access at this stage. PBS-side artifacts I'd already created (hazel@pbs user + ACL on /datastore/nas-primary/housemate) were rolled back; backups continue to land in root namespace via the existing pbs-daily job.
Two CLI bugs in the original step 6 caught and corrected:
proxmox-backup-manager namespace createdoes not exist in PBS 4.x. The original draft assumed it did. Namespaces auto-create on first backup write, or via the web UI / REST API. Future-enhancement block in step 6 reflects this.acl updatearg order is<path> <role> --auth-id <id>, not<path> <auth-id> --role <role>. Path and role are both positional; auth ID is a flag.
Lesson for future runbook drafting: validate proxmox-backup-manager and pveum subcommands against --help before sketching command sequences. Cheap to do, would have caught both bugs pre-execution.
Related¶
- Phase 8 — Network segmentation (deferred) — the future L2 isolation
- Backup & Restore runbook — base PBS workflow