test(install): cover checksum and provenance verification

Pin fail-closed installer paths for missing manifests, verifier
fallback, and the skip-verify escape hatch (#1267).
This commit is contained in:
mohammad junayd 2026-09-14 17:47:03 +04:00
parent 0636584eef
commit a079b6c418

View file

@ -48,14 +48,42 @@ esac
""",
)
_write_executable(mock_bin / "docker", "#!/bin/sh\nexit 0\n")
# Shadow any real gh/cosign on PATH. Behaviour is driven by env flags.
_write_executable(
mock_bin / "gh",
"""#!/bin/sh
# Prefer this mock over a real gh on PATH so tests do not hit GitHub.
if [ "$1" = "attestation" ]; then
if [ -n "${STRIX_TEST_NO_VERIFIER:-}" ]; then
exit 1
fi
if [ "$1" = "attestation" ] && [ "$2" = "verify" ]; then
if [ "$3" = "--help" ]; then
exit 0
fi
printf '%s\\n' "$*" >> "$STRIX_TEST_GH_LOG"
if [ -n "${STRIX_TEST_GH_FAIL_VERIFY:-}" ]; then
exit 1
fi
exit 0
fi
exit 1
""",
)
_write_executable(
mock_bin / "cosign",
"""#!/bin/sh
if [ -n "${STRIX_TEST_NO_VERIFIER:-}" ]; then
exit 1
fi
if [ "$1" = "verify-blob-attestation" ]; then
if [ "$2" = "--help" ]; then
[ -n "${STRIX_TEST_USE_COSIGN:-}" ] && exit 0
exit 1
fi
printf '%s\\n' "$*" >> "$STRIX_TEST_COSIGN_LOG"
[ -n "${STRIX_TEST_USE_COSIGN:-}" ] && exit 0
exit 1
fi
exit 1
""",
)
_write_executable(
@ -75,11 +103,19 @@ while [ "$#" -gt 0 ]; do
printf '%s\\n' "$1" >> "$STRIX_TEST_CURL_LOG"
shift
done
if [ -n "${STRIX_TEST_CURL_FAIL:-}" ]; then
case "$url" in
*"$STRIX_TEST_CURL_FAIL"*) exit 22 ;;
esac
fi
case "$url" in
*/SHA256SUMS)
name=$(basename "$STRIX_TEST_ARCHIVE")
if [ -n "${STRIX_TEST_BAD_CHECKSUM:-}" ]; then
printf '%s %s\\n' "0" "$name" > "$output"
elif [ -n "${STRIX_TEST_SUMS_WRONG_NAME:-}" ]; then
hash=$(sha256sum "$STRIX_TEST_ARCHIVE" | awk '{print $1}')
printf '%s %s\\n' "$hash" "other-file.tar.gz" > "$output"
else
hash=$(sha256sum "$STRIX_TEST_ARCHIVE" | awk '{print $1}')
printf '%s %s\\n' "$hash" "$name" > "$output"
@ -113,6 +149,8 @@ def _create_installer_environment(
download_path = tmp_path / "downloads"
download_path.mkdir()
curl_log_path = tmp_path / "curl.log"
gh_log_path = tmp_path / "gh.log"
cosign_log_path = tmp_path / "cosign.log"
environment = {
"HOME": str(home_path),
"XDG_CONFIG_HOME": str(home_path / ".config"),
@ -121,6 +159,8 @@ def _create_installer_environment(
"TMPDIR": str(download_path),
"STRIX_TEST_ARCHIVE": str(archive_path),
"STRIX_TEST_CURL_LOG": str(curl_log_path),
"STRIX_TEST_GH_LOG": str(gh_log_path),
"STRIX_TEST_COSIGN_LOG": str(cosign_log_path),
"VERSION": RELEASE_VERSION,
}
return environment, home_path, curl_log_path
@ -154,7 +194,20 @@ def test_installer_downloads_and_runs_linux_arm64_release(tmp_path: Path) -> Non
assert result.returncode == 0, result.stderr
expected_filename = f"strix-{RELEASE_VERSION}-{RELEASE_TARGET}.tar.gz"
assert expected_filename in curl_log_path.read_text(encoding="utf-8")
curl_log = curl_log_path.read_text(encoding="utf-8")
assert expected_filename in curl_log
assert f"releases/download/v{RELEASE_VERSION}/SHA256SUMS" in curl_log
assert f"strix-{RELEASE_TARGET}.intoto.jsonl" in curl_log
assert "Checksum verified" in result.stdout
assert "Provenance verified" in result.stdout
gh_log = (tmp_path / "gh.log").read_text(encoding="utf-8")
assert "--repo usestrix/strix" in gh_log
assert "--bundle strix-linux-arm64.intoto.jsonl" in gh_log
assert (
"--signer-workflow usestrix/strix/.github/workflows/build-release.yml" in gh_log
)
assert "--deny-self-hosted-runners" in gh_log
assert not (tmp_path / "cosign.log").exists()
installed_binary = home_path / ".strix/bin/strix"
installed_result = subprocess.run( # noqa: S603
@ -215,3 +268,151 @@ def test_installer_leaves_existing_install_on_checksum_failure(tmp_path: Path) -
check=True,
)
assert installed_result.stdout.strip() == "strix 1.0.0"
def test_installer_rejects_missing_checksum_manifest(tmp_path: Path) -> None:
repository_root = Path(__file__).resolve().parents[1]
archive_path = _create_release_archive(tmp_path)
mock_bin = _create_mock_commands(tmp_path, machine="aarch64")
environment, home_path, _curl_log_path = _create_installer_environment(
tmp_path,
archive_path,
mock_bin,
)
environment["STRIX_TEST_CURL_FAIL"] = "SHA256SUMS"
result = _run_installer(repository_root, environment)
assert result.returncode != 0
assert "Failed to download checksum manifest" in result.stdout
assert not (home_path / ".strix/bin/strix").exists()
def test_installer_rejects_checksum_manifest_without_archive_entry(
tmp_path: Path,
) -> None:
repository_root = Path(__file__).resolve().parents[1]
archive_path = _create_release_archive(tmp_path)
mock_bin = _create_mock_commands(tmp_path, machine="aarch64")
environment, home_path, _curl_log_path = _create_installer_environment(
tmp_path,
archive_path,
mock_bin,
)
environment["STRIX_TEST_SUMS_WRONG_NAME"] = "1"
result = _run_installer(repository_root, environment)
assert result.returncode != 0
assert "No SHA256SUMS entry" in result.stdout
assert not (home_path / ".strix/bin/strix").exists()
def test_installer_rejects_missing_provenance_bundle(tmp_path: Path) -> None:
repository_root = Path(__file__).resolve().parents[1]
archive_path = _create_release_archive(tmp_path)
mock_bin = _create_mock_commands(tmp_path, machine="aarch64")
environment, home_path, _curl_log_path = _create_installer_environment(
tmp_path,
archive_path,
mock_bin,
)
environment["STRIX_TEST_CURL_FAIL"] = "intoto.jsonl"
result = _run_installer(repository_root, environment)
assert result.returncode != 0
assert "Failed to download provenance bundle" in result.stdout
assert "Checksum verified" in result.stdout
assert not (home_path / ".strix/bin/strix").exists()
def test_installer_rejects_failed_gh_attestation_verify(tmp_path: Path) -> None:
repository_root = Path(__file__).resolve().parents[1]
archive_path = _create_release_archive(tmp_path)
mock_bin = _create_mock_commands(tmp_path, machine="aarch64")
environment, home_path, _curl_log_path = _create_installer_environment(
tmp_path,
archive_path,
mock_bin,
)
environment["STRIX_TEST_GH_FAIL_VERIFY"] = "1"
result = _run_installer(repository_root, environment)
assert result.returncode != 0
assert "gh attestation verify failed" in result.stdout
assert not (home_path / ".strix/bin/strix").exists()
assert not (tmp_path / "cosign.log").exists()
def test_installer_uses_cosign_when_gh_cannot_verify(tmp_path: Path) -> None:
repository_root = Path(__file__).resolve().parents[1]
archive_path = _create_release_archive(tmp_path)
mock_bin = _create_mock_commands(tmp_path, machine="aarch64")
environment, home_path, _curl_log_path = _create_installer_environment(
tmp_path,
archive_path,
mock_bin,
)
environment["STRIX_TEST_USE_COSIGN"] = "1"
_write_executable(
mock_bin / "gh",
"#!/bin/sh\nexit 1\n",
)
result = _run_installer(repository_root, environment)
assert result.returncode == 0, result.stderr
assert "Provenance verified" in result.stdout
assert "(cosign)" in result.stdout
cosign_log = (tmp_path / "cosign.log").read_text(encoding="utf-8")
assert "--new-bundle-format" in cosign_log
assert "--certificate-oidc-issuer https://token.actions.githubusercontent.com" in (
cosign_log
)
assert "build-release.yml" in cosign_log
assert "--type slsaprovenance1" in cosign_log
assert (home_path / ".strix/bin/strix").exists()
def test_installer_rejects_when_no_provenance_verifier_is_available(
tmp_path: Path,
) -> None:
repository_root = Path(__file__).resolve().parents[1]
archive_path = _create_release_archive(tmp_path)
mock_bin = _create_mock_commands(tmp_path, machine="aarch64")
environment, home_path, _curl_log_path = _create_installer_environment(
tmp_path,
archive_path,
mock_bin,
)
environment["STRIX_TEST_NO_VERIFIER"] = "1"
result = _run_installer(repository_root, environment)
assert result.returncode != 0
assert "Neither a usable 'gh' nor 'cosign'" in result.stdout
assert not (home_path / ".strix/bin/strix").exists()
def test_installer_skip_verify_does_not_download_manifests(tmp_path: Path) -> None:
repository_root = Path(__file__).resolve().parents[1]
archive_path = _create_release_archive(tmp_path)
mock_bin = _create_mock_commands(tmp_path, machine="aarch64")
environment, home_path, curl_log_path = _create_installer_environment(
tmp_path,
archive_path,
mock_bin,
)
environment["STRIX_INSTALL_SKIP_VERIFY"] = "1"
result = _run_installer(repository_root, environment)
assert result.returncode == 0, result.stderr
curl_log = curl_log_path.read_text(encoding="utf-8")
assert "SHA256SUMS" not in curl_log
assert "intoto.jsonl" not in curl_log
assert "skipping checksum and provenance checks" in result.stdout
assert (home_path / ".strix/bin/strix").exists()
assert not (tmp_path / "gh.log").exists()