Skip to content

REQ 105

sergio velderrain edited this page Nov 10, 2026 · 1 revision

REQ-105: Refuse to package an appliance that carries an Actions runner

Requirement

The appliance packager shall package a source VM only after a scan of that VM, in the state that it packages, finds no GitHub Actions runner.

Rationale

vagrant package --base packages the source VM's current state, and the appliance's register-runner phase installs a runner on the source VM without taking a snapshot. A box that carried the runner's service unit or its configuration (.runner, .credentials) would start a copy of that runner in every clone and hand its credentials to everyone who gets the box. The appliance's refuse clone profile catches a runner unit only after a box exists (VITechnologies/projectbuddy#192, the unit check of REQ-103); this requirement refuses earlier, when the box is packaged (VITechnologies/projectbuddy#195).

Fit Criterion

Before it plans or changes anything, package-vagrant-box.py requires the source VM to be running with exactly one loopback SSH forwarding rule for the given port, enrolls only the SSH host key that the verified base receipt records, and, within one guest boot (the boot ID is read before and after), lists actions.runner.* units with the clone check's two systemctl queries and lists every .runner or .credentials entry outside /dev, /proc, /run, and /sys with sudo find. It then shuts the guest down itself and packages only if VirtualBox reports the same VM poweroff at the scanned snapshot. Its projectbuddy/ubuntu-vagrant-box@2 receipt records the scan in a runnerScan block (bootId, empty runnerUnits and runnerConfigurations, the four skippedRoots, and a UTC scannedAt), and verify-vagrant-box-receipt.py and verify-vagrant-clone.py refuse @1 receipts. Rejected: a source VM with an actions.runner.* unit, a .runner file, or a .credentials file, a scan step that fails, or a boot ID that changes is refused with exit code 2 before any change, and the VM keeps running; a guest that does not power off, or powers off at another snapshot, fails with exit code 1 and leaves no box; a box receipt whose scan found anything, skipped other roots, or is missing is refused.

Verification

Planned, TEST-107; not yet performed live. Offline fixture tests drive the packager against a simulated host and guest. A runner unit, a runner configuration file, each failing scan step, and a changed boot ID are refused with nothing changed; a guest that ignores power-off or stops at another snapshot leaves no box; both verifiers refuse @1 receipts, and the box verifier refuses receipts whose scan found anything or is malformed. A mutation check of the new guards kills every mutant. The existing appliance box has an @1 receipt and must be packaged again.

Source

Software-Requirements-Specification

Priority

High

TestID

TEST-107

TestArtifact

scripts/tests/test_package_vagrant_box.py runner scan, power-off, and receipt cases, and scripts/tests/test_vagrant_clone.py box receipt cases

CodeRef

vm/ubuntu-labview/package-vagrant-box.py, scripts/vagrant_clone/guest.py (host-key enrollment, the runner scan, and power-off), scripts/vagrant_clone/core.py (the SSH forwarding check and the runner unit queries), vm/ubuntu-labview/verify-vagrant-box-receipt.py, and vm/ubuntu-labview/verify-vagrant-clone.py

Status

Planned; offline fixture tests pass, no live proof yet

Clone this wiki locally