Harden installer: minisign signatures, manifest schema validation, opt-in tracking - #146
Harden installer: minisign signatures, manifest schema validation, opt-in tracking#146B1ZZ211 wants to merge 4 commits into
Conversation
…t-in tracking Security hardening of the curl|bash installer, based on a full audit of the script currently deployed at adal.sylph.ai/install.sh: - minisign (Ed25519) artifact verification with embedded public key; enforced whenever a .minisig is published, with ADAL_REQUIRE_SIGNATURE=1 for hard-fail environments (transition mode while signatures roll out) - manifest schema validation: version/platform/checksum/size/filename are validated before anything is trusted; malformed manifests are refused - JSON parsing via jq -> python3 -> sed fallback (was sed-only; the old parser matched the nested 'platforms' key only by accident) - strict semver version validation + tarball filename regex (blocks command injection / path traversal in URLs and local-tarball installs) - hard failure when the manifest/checksum is unavailable (no silent skip) - EXIT trap cleans the temp dir on error/signal; verified extraction via the real entry point (adal / adal.cmd) - install tracking is now OPT-IN (--track / ADAL_TRACK=1) and requests carry an HMAC-SHA256 signature + timestamp + nonce - actionable error for the unpublished linux-arm64-musl platform - fixed 2>/devuhl typo -> 2>/dev/null Includes: scripts/sign-release.sh (release-side signing), a zero-dependency test suite (tests/) with full E2E coverage of tamper/signature/schema/tracking paths, GitHub Actions CI (shellcheck + tests), SECURITY.md (threat model, key custody, org-side actions) and RELEASE.md (deploy/signing/HMAC runbook, musl CI matrix). Tests: 2 suites, all passing; shellcheck clean.
The previous private key blob was pasted into a terminal and a chat transcript; minisign verified it signs without a password, so the key was treated as compromised and rotated. - install.sh: SIGNING_PUBLIC_KEY -> RWSZUbVM/EZtFEz8cAk+0zEnPI2cCSQFuSuK4xp0KUlP+Wdf71tvUl7C - scripts/sign-release.sh: same - test suite re-run: all passing
🔑 Release signing key — handoverThis PR hardens the installer with minisign (Ed25519) artifact verification. Per Public key — already embedded in this PR's Private key ( Integrity reference — SHA-256 of the private key file, so the copy you store can be verified against mine:
Next steps for maintainers
The contributor copy of the private key will be deleted from this laptop once the pipeline confirms receipt. |
Summary
Security hardening of the
curl | bashinstaller, based on a full differential audit of the script currently deployed atadal.sylph.ai/install.sh. The hardened installer is a complete, tested replacement atinstall.sh, with release-side tooling, a test suite, and runbooks.Key changes
<tarball>.minisigusing a public key embedded in the installer. Enforced whenever a signature is published;ADAL_REQUIRE_SIGNATURE=1makes a missing signature/minisign a hard failure. Transition mode warns while the pipeline is not yet publishing.minisigfiles.version,platforms.<platform>.filename/checksum/sizeare validated before anything is trusted; malformed manifests are refused, never silently trusted.jq→python3→sedfallback. The old sed-only parser extracted the nestedplatformskey only by accident; a manifest format change would have silently disabled checksum verification.--versionand--local-tarballnames.adalexecutable /adal.cmd).--track/ADAL_TRACK=1); requests carry an HMAC-SHA256 signature + timestamp + nonce (server-side verification reference in RELEASE.md).linux-arm64-muslplatform.2>/devuhltypo →2>/dev/null.New files
install.shscripts/sign-release.sh--checkmode included)tests/SECURITY.mdRELEASE.mdTesting —
bash tests/run.sh: 2 suites, all passing.shellcheck --severity=warning: clean. E2E builds a fake signed release served overfile://and proves: happy path with signature verified, tampered tarball rejected (size+checksum), forged-manifest attack caught by the signature, missing-signature transition mode,ADAL_REQUIRE_SIGNATURE=1hard fail, schema violations refused, and the opt-in tracking POST with a valid HMAC captured by a local HTTP server.Not included in this PR (needs
workflowscope / org access) — CI workflow; see below.CI workflow (for
.github/workflows/ci.yml)Org-side follow-ups (details in SECURITY.md / RELEASE.md)
install.shtoadal.sylph.ai/install.sh(this repo is the community home; the live script is built from a private pipeline)..minisigfiles for every artifact viascripts/sign-release.sh; move the release signing key into CI secrets.linux-arm64-muslto the release matrix (or stop advertising it).