mirror of
https://github.com/usestrix/strix.git
synced 2026-09-24 00:51:20 +00:00
fix(install): verify Sigstore provenance before extract
Fail closed unless gh or cosign can check the published bundle against this release workflow (#1267).
This commit is contained in:
parent
8d09cff912
commit
d61e0a2a63
2 changed files with 91 additions and 0 deletions
|
|
@ -85,6 +85,10 @@ fi
|
|||
|
||||
filename="$APP-${specific_version}-${target}${archive_ext}"
|
||||
url="https://github.com/$REPO/releases/download/v${specific_version}/$filename"
|
||||
bundle_name="strix-${target}.intoto.jsonl"
|
||||
bundle_url="https://github.com/$REPO/releases/download/v${specific_version}/$bundle_name"
|
||||
SIGNER_WORKFLOW="$REPO/.github/workflows/build-release.yml"
|
||||
CERT_IDENTITY_REGEXP="^https://github.com/${REPO}/.github/workflows/build-release.yml"
|
||||
|
||||
print_message() {
|
||||
local level=$1
|
||||
|
|
@ -129,6 +133,75 @@ check_existing_installation() {
|
|||
fi
|
||||
}
|
||||
|
||||
abort_unverified() {
|
||||
echo -e "${RED}✗ Refusing to install an unverified binary.${NC}"
|
||||
echo -e "${RED}Re-run with STRIX_INSTALL_SKIP_VERIFY=1 to override (at your own risk).${NC}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
gh_can_verify_attestation() {
|
||||
command -v gh >/dev/null 2>&1 && gh attestation verify --help >/dev/null 2>&1
|
||||
}
|
||||
|
||||
cosign_can_verify_attestation() {
|
||||
command -v cosign >/dev/null 2>&1 && cosign verify-blob-attestation --help >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Fail-closed provenance check. The bundle is signed Sigstore SLSA provenance
|
||||
# for this workflow; checksum verification (same-origin) is a separate step.
|
||||
# Prefer `gh attestation verify`; otherwise a local `cosign`. We do not
|
||||
# bootstrap cosign — current releases are ~140MB, which is too heavy for
|
||||
# curl|bash. Missing verifier or a failed check aborts before extract.
|
||||
verify_provenance() {
|
||||
local file=$1
|
||||
local bundle=$2
|
||||
|
||||
if [ -n "${STRIX_INSTALL_SKIP_VERIFY:-}" ]; then
|
||||
echo -e "${YELLOW}⚠ STRIX_INSTALL_SKIP_VERIFY set — skipping provenance verification (at your own risk).${NC}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ ! -s "$bundle" ]; then
|
||||
echo -e "${RED}✗ Missing provenance bundle ${bundle}.${NC}"
|
||||
abort_unverified
|
||||
fi
|
||||
|
||||
echo -e "${MUTED}Verifying Sigstore provenance...${NC}"
|
||||
|
||||
if gh_can_verify_attestation; then
|
||||
if gh attestation verify "$file" \
|
||||
--repo "$REPO" \
|
||||
--bundle "$bundle" \
|
||||
--signer-workflow "$SIGNER_WORKFLOW" \
|
||||
--predicate-type "https://slsa.dev/provenance/v1" \
|
||||
--deny-self-hosted-runners; then
|
||||
echo -e "${GREEN}✓ Provenance verified${NC} ${MUTED}(gh)${NC}"
|
||||
return 0
|
||||
fi
|
||||
echo -e "${RED}✗ gh attestation verify failed.${NC}"
|
||||
abort_unverified
|
||||
fi
|
||||
|
||||
if cosign_can_verify_attestation; then
|
||||
if cosign verify-blob-attestation \
|
||||
--bundle "$bundle" \
|
||||
--new-bundle-format \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
|
||||
--certificate-identity-regexp "$CERT_IDENTITY_REGEXP" \
|
||||
--type slsaprovenance1 \
|
||||
"$file"; then
|
||||
echo -e "${GREEN}✓ Provenance verified${NC} ${MUTED}(cosign)${NC}"
|
||||
return 0
|
||||
fi
|
||||
echo -e "${RED}✗ cosign verify-blob-attestation failed.${NC}"
|
||||
abort_unverified
|
||||
fi
|
||||
|
||||
echo -e "${RED}✗ Neither a usable 'gh' nor 'cosign' was found; cannot verify provenance.${NC}"
|
||||
echo -e "${MUTED}Install GitHub CLI (gh) or cosign, then re-run.${NC}"
|
||||
abort_unverified
|
||||
}
|
||||
|
||||
check_version() {
|
||||
check_existing_installation
|
||||
|
||||
|
|
@ -158,6 +231,14 @@ download_and_install() {
|
|||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${MUTED}Downloading provenance...${NC}"
|
||||
if ! curl -sfL -o "$bundle_name" "$bundle_url" || [ ! -s "$bundle_name" ]; then
|
||||
echo -e "${RED}✗ Failed to download provenance bundle.${NC}"
|
||||
abort_unverified
|
||||
fi
|
||||
|
||||
verify_provenance "$filename" "$bundle_name"
|
||||
|
||||
echo -e "${MUTED}Extracting...${NC}"
|
||||
if [ "$os" = "windows" ]; then
|
||||
unzip -q "$filename"
|
||||
|
|
|
|||
|
|
@ -48,6 +48,16 @@ esac
|
|||
""",
|
||||
)
|
||||
_write_executable(mock_bin / "docker", "#!/bin/sh\nexit 0\n")
|
||||
_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
|
||||
exit 0
|
||||
fi
|
||||
exit 1
|
||||
""",
|
||||
)
|
||||
_write_executable(
|
||||
mock_bin / "curl",
|
||||
"""#!/bin/sh
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue