v0.6.5
Security & live-integration CI. Closes an A2A bind auth-bypass, hardens identifier validation,
fixes a plan-honesty gap, and lands a substantial live-integration smoke harness that exercises the
trust spine against a real cluster. No new tools (145).
Security
- A2A auth-bypass: an empty bind host bound every interface without auth.
_is_publictreated
an empty/whitespace host as non-public (bool("")isFalse), soPROXIMO_A2A_HOST=""bound
0.0.0.0— all interfaces — while skipping the bearer-token requirement a non-loopback bind is
meant to force. An empty,None, or whitespace-only host is now classified public: the A2A control
endpoint refuses to start on it without a bearer token, fail-closed like any other public bind. - Identifier validation hardened.
vmidis validated as ASCII digits (wasstr.isdigit(), which
accepts non-ASCII Unicode digits);realmidrejects./..dot-segments (the path-traversal class
closed across the other identifiers in 0.6.2/0.6.3); firewall alias CIDRs are validated; and the
TLS-verify default is pinned fail-closed by test.
Fixed
- Plan honesty:
pve_network_iface_updatepreview was blind to stagedoptions. The dry-run did
not disclose every field it would stage, and a reservedtypekey could be passed through. The plan
now discloses the staged fields and rejects the reserved key.
Added
- Public-tree leak-gate catches bare internal hostnames. The release leak-audit previously matched
only dotted internal TLDs (.lan/.internal/.intranet); it now also refuses bare internal
hostnames via an internal-only denylist (itself stripped from the public tree). - Registry-completeness gate (CI). A test pins the read-only tool set and asserts every other
registered tool takes aconfirm=parameter, so a new mutating tool cannot ship un-gated. (It proves
a mutator has the confirm gate, not thatconfirm=Falseno-ops.) - Live-integration smoke harness. A phase-tagged orchestrator (
scripts/live-smoke/run-all.py:
read → plan → mutate → destroy, escalating by blast radius) plus planes for the mutate slice,
access-CRUD, storage-admin, and PBS (namespace / snapshot-delete / prune / gc / verify). Each plane
is guarded by an independent default-deny allowlist (safety.py) — a VMID/storage/PBS-host not named
as a test target is refused before any API call, a second safety layer beneath the scoped token —
is self-seeding and self-cleaning, and SKIPs when its scoped env is unset. The PBSverifysmoke
asserts real, scoped verification (the target snapshot'sverification.state == 'ok'and a decoy
snapshot left untouched). It is wired to a nightly advisory CI job (non-blocking); the read+plan
slice runs with only a read token and is proven end-to-end against a real cluster. - Characterization fixtures pin the blast engine to real PVE response shapes
(tests/test_live_shapes.py), locking the backup-job selection-mode serialization the
guest_destroyresolver depends on against ground truth — real PVE omits unsetpool/vmidkeys
rather than sendingnull, serializesallas an int andexcludeas a comma-string, and always
carries a syntheticcurrentsnapshot entry. Shape-only and credential-free, so they run in the
fast suite.
Docs
- Overclaim corrections. Fixed a self-contradicting "the hypervisor is never touched" line, the
PROVE "verifiable" framing, and the PLAN "gate" wording; replaced hardcoded test counts with
drift-resistant phrasing.