Skip to content

v0.39.0: the junction gets its law

Choose a tag to compare

@john-broadway john-broadway released this 01 Sep 00:28

The junction gets its law.

A Proxmox server is two roots on two planes. The product plane has RBAC, task logs, an API. The metal plane is a root shell, and every AI-for-Proxmox integration picks a lane at that fork: API wrapper (governed, incomplete) or root SSH (complete, ungoverned). Proximo takes the API lane and doors the shell residue with its own discipline, but the guest shell reach itself answered to no PVE privilege: Proxmox exposes no REST endpoint for container exec, and its ACL model cannot scope an ssh key.

0.39.0 closes the span:

  • The mirror. With PROXIMO_REACH_PRIVILEGE set, ct_exec and ct_psql run only where the SERVED token holds that privilege, asked of PVE per guest path (/access/permissions?path=/vms/<id>), so propagation and deeper-NoAccess revocation are resolved by PVE itself. Fail-closed on an unanswerable map. Intersection with the allowlist: the mirror only narrows. Dormant until configured, zero behavior change unset. The shell channel now obeys the same permission table the API channel always obeyed.
  • The witness. The reach grant, the standing perimeter every PLAN, CONSENT and PROVE runs inside, was the one mutation the PROVE ledger never saw. Now every serve start snapshots the resolved grant on every door and records any delta: what was added, what was removed, per lane, per source. While the mirror enforces, the snapshot also derives the served token's per-guest reach from PVE, so a pveum grant or revoke between starts lands as a witnessed delta. Every change to reach, on either side of the junction, reaches the ledger.
  • The evidence. proximo reach-audit prints the decision packet for choosing the privilege, live from your server: what each candidate actually gates in stock PVE (VM.Console gates a login prompt, not execution), which roles carry it, who holds those roles today, and the served token's derived per-guest reach compared against the current allowlist.
  • The posture. proximo harden reads which opt-in pillars stand (CONSENT, CONTAIN, the off-box PROVE anchor, the ARM pattern) and prints the exact operator-shell recipe for each empty one, verify line included. --check exits 1 while any core station is empty: cron teeth that keep opt-in from drifting into forgotten.
  • The host side. Two read-only node tools, pve_node_logs and pve_node_diagnose, open the read half of the host lane behind their own opt-in and the mirror at /nodes/<node>. There is deliberately no node_exec: the host mutation lane stays undoored until its fail-posture is designed rather than defaulted.
  • The argument. docs/JUNCTION.md states the design in full, honest limits included: root cannot be caged by anything it runs. This is self-governance made auditable, and switching the mirror off is itself a witnessed reach change.

Also in 0.39.0: an unknown CLI verb exits 2 with usage instead of falling through to serving; three standing pyright errors fixed at their causes; the test suite can no longer write the dev box's real PROVE ledger; CI tokens ride scoped auth headers, never the clone URL or ARGV. 908 tools, up from 906.

Where to read more

Install: uvx proximo-proxmox · pip install proximo-proxmox · ghcr.io/john-broadway/proximo:0.39.0