What
install.sh is the public curl-installer entry point (curl … | bash). It carries two security-critical fail-closed branches:
install.sh:60-63 — bundle sha256 vs the release manifest; on mismatch it must fail and install nothing.
install.sh:74-79 — cosign verify-blob against the repo-pinned key; a present-but-bad signature is meant to be fatal, while an absent one degrades to a note.
Neither is tested. The only coverage is tests/stack/run.sh:3774-3784, which stubs uname and asserts the two host gates:
assert_contains "install.sh refuses non-amd64" "$out" "x86_64-only"
assert_contains "install.sh refuses non-Linux" "$out" "runs on Linux"
Everything after the host gate — tag resolution, download, checksum verify, signature verify, the $DIR already-exists guard — is unexercised. Deleting the [ "$GOT" = "$WANT" ] comparison, or flipping the cosign check to non-fatal, keeps the suite green.
Why it matters
This is the path a new operator runs before they have any of the repo's other defenses. The in-bundle protections (verify_release_images, pinned digests) only start applying after a tampered bundle has already been extracted and executed.
Note the asymmetry these tests would pin down: a missing signature is a note, a bad one is fatal. That distinction is the whole security property and nothing currently holds it in place.
Tier
Tier 1, in tests/stack/run.sh, using the PATH-stub pattern the file already uses for uname. Stub curl to serve a fixture bundle + manifest, sha256sum, and cosign, then assert:
- manifest sha256 mismatch → non-zero, nothing extracted, message names the refusal
- manifest sha256 match → proceeds
- manifest with no sha256 line → proceeds with the pre-v1.15 note (not a silent pass)
cosign present + signature present + verify fails → non-zero, nothing extracted
cosign present + no signature published → proceeds with the note
cosign absent → proceeds with the note
PITHEAD_DIR already exists → refuses before any download
install.sh execs ./pithead setup at the end, so the stub set needs a pithead that exits 0 for the positive cases.
Found during the develop-v2 quality pass (PR #867).
What
install.shis the public curl-installer entry point (curl … | bash). It carries two security-critical fail-closed branches:install.sh:60-63— bundle sha256 vs the release manifest; on mismatch it mustfailand install nothing.install.sh:74-79—cosign verify-blobagainst the repo-pinned key; a present-but-bad signature is meant to be fatal, while an absent one degrades to a note.Neither is tested. The only coverage is
tests/stack/run.sh:3774-3784, which stubsunameand asserts the two host gates:Everything after the host gate — tag resolution, download, checksum verify, signature verify, the
$DIRalready-exists guard — is unexercised. Deleting the[ "$GOT" = "$WANT" ]comparison, or flipping the cosign check to non-fatal, keeps the suite green.Why it matters
This is the path a new operator runs before they have any of the repo's other defenses. The in-bundle protections (
verify_release_images, pinned digests) only start applying after a tampered bundle has already been extracted and executed.Note the asymmetry these tests would pin down: a missing signature is a note, a bad one is fatal. That distinction is the whole security property and nothing currently holds it in place.
Tier
Tier 1, in
tests/stack/run.sh, using the PATH-stub pattern the file already uses foruname. Stubcurlto serve a fixture bundle + manifest,sha256sum, andcosign, then assert:cosignpresent + signature present + verify fails → non-zero, nothing extractedcosignpresent + no signature published → proceeds with the notecosignabsent → proceeds with the notePITHEAD_DIRalready exists → refuses before any downloadinstall.shexecs./pithead setupat the end, so the stub set needs apitheadthat exits 0 for the positive cases.Found during the
develop-v2quality pass (PR #867).