mirror of
https://github.com/certctl-io/certctl.git
synced 2026-08-25 16:01:26 +02:00
Acquisition-audit RED-007 closure (Sprint 7 ACQ, 2026-05-16).
Pre-2026-05-16, install-agent.sh downloaded the agent binary with
`curl -sSL -f` from GitHub Releases and ran chmod +x — no integrity
check, no signature verification. A tampered release-asset upload
(e.g. compromised maintainer GH token) or a misnamed asset would
install silently. HTTPS already prevents in-flight tampering, but
the release-surface tamper case was wide-open.
The download_binary() function now performs two independent
verifications BEFORE install_binary copies to $INSTALL_DIR:
1. SHA-256 against the release-published checksums.txt
Every release publishes checksums.txt (sha256sum-format) at
the same RELEASE_URL. The script downloads it, looks up the
binary's expected hash by name, and compares against
sha256sum (Linux) or shasum -a 256 (macOS — both fallbacks
tried). Mismatch rejects the install and exits 1. A
missing-entry rejection is also exit 1 because an
inconsistent release surface is itself a supply-chain
anomaly.
2. Cosign keyless verify against the GitHub Actions OIDC identity
When cosign is installed, the script downloads
<binary>.sigstore.json and runs:
cosign verify-blob \\
--bundle <bundle> \\
--certificate-identity-regexp "^https://github.com/${GITHUB_REPO}/" \\
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \\
<binary>
This pins the signature to the certctl-io/certctl release
workflow's OIDC identity (see .github/workflows/release.yml).
When cosign is NOT installed, the script logs a clear WARN
pointing at the cosign install snippet and proceeds with
SHA-256 verification only. Operators in regulated environments
MUST install cosign and re-run.
What this DOES NOT change
=========================
- The script's bash-piped install pattern (curl|bash) is not
refactored. The audit prompt's NON-GOAL pin ("Stay shell. Do
not refactor install-agent.sh into a binary distribution.") is
honored.
- HTTPS-only download semantics are unchanged (already in place).
- The unsupported-platform refusal at L38-49 is unchanged (already
in place).
Verified locally: bash -n syntax clean. The integration smoke test
(deploy/test/install-agent-smoke.sh) that the audit prompt
optionally suggested was NOT added — the verification logic is
straightforward enough that the inline if/else error paths are
self-documenting and the operator-visible failure messages are the
test.
27 KiB
27 KiB