Findings only — no script, profile or build file changed; no ISO built, nothing published. documentation/audits/SPIKE-universal-iso-2026-07-31.md - R-139 (HIGH): a disk filter matching >1 device does NOT fail safe. Observed in a nested VM — the installer silently picked one of two matching disks and wiped it; validate-answer accepts such an answer. The 'filter did not match any devices' guard covers the ZERO-match case only. - No udev property distinguishes an internal system disk from external media. Measured on demo-felhom with its 1TB external attached: ID_BUS='ata' for BOTH, lsblk RM=0 for both, and device-info exposes no removability property. demo-hp's NVMe carries no ID_BUS/ID_TYPE at all. - R-141 (HIGH): the answer schema makes a root credential mandatory, but root-password-hashed='*' validates AND installs to completion. [first-boot].ordering accepts 'before-network', the only ordering that closes the exposure window structurally. - Q3: prepare-iso leaves grub.cfg byte-identical to stock (15 entries, automated AND interactive) — a two-entry menu is purely a Felhom grub.cfg.tmpl change. - R-129 resolved: demo-hp's key is the operator's own, added post-install; demo-felhom's IS baked by an uncommitted profile. The reachable-before-rotation measurement FAILED twice and is recorded as failed, not inferred. Opens R-139..R-147; restates R-128.
5.7 KiB
REPORT — SPIKE: what does a genuinely universal ISO require? (2026-07-31)
Written as
REPORT-universal-iso-spike.md, notREPORT.md: the shared file was overwritten at 09:24 today by the hub v0.85.0 Network-card session, and the standing rule is that the second session in a shared clone never touches it.
Class: Spike. Output is a findings document. No production code was changed, no ISO was built,
nothing was published. Full evidence:
documentation/audits/SPIKE-universal-iso-2026-07-31.md.
Why this ran
The ISO build/publish task stopped before its Part 2. Its Part 0 found that every ISO bakes a root
password hash into /answer.toml, and that generic.profile picks a disk by the name sda rather
than by identity — both of which make a public download a product decision. This spike establishes
what a genuinely universal image would require.
What was answered
Q1 — disk selection. The central finding, and it is worse than the known hazard.
A filter that matches more than one device does not fail safe. Observed in a nested VM with two
identical disks and filter.ID_SERIAL_SHORT = "SPIKE*": the installer silently selected one and wiped
it (disk0 hash de001102… → 382b55ca…; disk1 byte-identical throughout). validate-answer
accepts the answer — it cannot know what the filter resolves to on the target. The
filter did not match any devices guard the safety profiles rely on covers the zero-match case
only.
And a filter that reliably matches exactly one disk on unseen hardware cannot be written, because
no property distinguishes an internal system disk from external media. Measured on demo-felhom
with its 1 TB external drive attached — the exact hazard configuration:
ID_BUSisatafor both (the external unit is a SATA drive in a USB caddy)lsblk RMis0for both;device-infoexposes no removability property at all- on
demo-hp, the NVMe carries noID_BUSand noID_TYPE— a different property set entirely - nothing anywhere expresses role: on
demo-hpthe system disk is the small SATA one and the big NVMe is customer data
Q2 — root password. A credential field is mandatory (One of global.root-password or global.root-password-hashed must be set), but a usable one is not: root-password-hashed = "*"
validates and installs to completion (guest powered itself off after 200 s using
reboot-mode = "power-off" as the completion signal). [first-boot].ordering also accepts
before-network — the only ordering that could close the exposure window structurally, since today's
bootstrap unit is After=network-online.target pveproxy.service and the pairing poll waits
indefinitely for the operator's bind.
Q3 — two-entry boot menu: yes, trivially. prepare-iso leaves grub.cfg byte-identical to
stock; a prepared ISO has 15 entries including automated and interactive. Felhom's repack is what
collapses it to one. No PVE-side obstacle exists.
Q4 — what else is baked. By enumeration against the stock ISO, not pattern-guessing: the pipeline
adds exactly six paths; both OS squashfs payloads are byte-identical to stock; all three first-boot
payloads match repo HEAD or carry only the hub URL. /answer.toml is the only secret-bearing content.
R-129 resolved. demo-hp's key is the operator's own, added post-install — not baked. But demo-felhom's is baked, by an uncommitted profile, so the "no baked key" claim was already false for one demo box and nothing recorded it.
What failed, and is recorded as failed
The reachable-before-rotation measurement was attempted twice and both attempts were invalid.
Attempt 1 reported a plausible 0 s that was an artefact — QEMU's hostfwd accepts on the host
before touching the guest, and the same run then failed to read an SSH banner at all. Attempt 2, with
a protocol-level detector, reported never because the install VM had no NIC, so the installed
system's interface config could not match the boot VM's. No number is reported. The structural
finding (unit ordering + unbounded pairing poll) stands instead and is the stronger claim.
Also not established: that the locked root account is actually locked (install completion is a different claim), and whether GRUB single-user recovery works — the latter gates the escrow-vs-discard ruling and should be measured before that ruling is made.
Asked of the operator
One decision, framed in §4.5 of the findings doc: escrow or discard a per-box root password. Not recommended either way — the D6 trust model argues against a hub-held fleet-wide vault, and an unbound box has no agent access, which is exactly when console access matters.
R-rows
R-139 (HIGH, multi-match wipes silently) · R-140 (device-match exits 0 on no-match) ·
R-141 (HIGH, mandatory + fleet-shared credential, unbounded window) · R-142 (FELHOM_ROOT_SSH_KEY
can ship a shared key, no assertion) · R-143 (retired kisfenyo@windows key still live on
demo-felhom) · R-144 (nested-probe ISO unreproducible — profile gone) · R-145 (variant naming
undocumented) · R-146 (root-password-hashed = "" validates) · R-147 (hash substituted into
the answer template's own comments) · R-128 restated (a comment, not an assertion).
Teardown
All three layers verified positively: demo-hp scratch removed and drill-r50/9201/storage.cfg
untouched, local-lvm never written; demo-felhom probe binary removed and its external drive observed
only; DooPlex scratchpad 3.2 GB → 28 K with the throwaway password shreded. No hub object was
created — confirmed by fetching the customer list and searching it, not by assertion. Nothing
deleted from felhom-iso/out/ (17 ISOs intact). Nothing published.