From aa702a72b44df9a8d9429d791a7b2197c97f6bc1 Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Tue, 30 Jan 2024 13:16:40 -0500 Subject: [PATCH] Sign checksums file and add SBOMs on release (#2548) * with release signature of checksums file * attach SBOMs to the release * update acceptance tests --------- Signed-off-by: Alex Goodman --- .binny.yaml | 22 ++++++++++++++++ .goreleaser.yaml | 25 +++++++++++++++++++ .../install/1_download_snapshot_asset_test.sh | 21 ++++++++++++++++ .../environments/Dockerfile-alpine-3.6 | 2 +- .../environments/Dockerfile-ubuntu-20.04 | 2 +- 5 files changed, 70 insertions(+), 2 deletions(-) diff --git a/.binny.yaml b/.binny.yaml index 9c6ce0b8e..d63122edf 100644 --- a/.binny.yaml +++ b/.binny.yaml @@ -1,4 +1,6 @@ tools: + + # we want to use a pinned version of binny to manage the toolchain (so binny manages itself!) - name: binny version: want: v0.6.3 @@ -6,6 +8,15 @@ tools: with: repo: anchore/binny + # used to produce SBOMs during release + - name: syft + version: + want: latest + method: github-release + with: + repo: anchore/syft + + # used to sign mac binaries at release - name: quill version: want: v0.4.1 @@ -13,6 +24,7 @@ tools: with: repo: anchore/quill + # used for linting - name: golangci-lint version: want: v1.55.2 @@ -20,6 +32,7 @@ tools: with: repo: golangci/golangci-lint + # used for showing the changelog at release - name: glow version: want: v1.5.1 @@ -27,6 +40,7 @@ tools: with: repo: charmbracelet/glow + # used for signing the checksums file at release - name: cosign version: want: v2.2.2 @@ -34,6 +48,7 @@ tools: with: repo: sigstore/cosign + # used in integration tests to verify JSON schemas - name: yajsv version: want: v1.4.1 @@ -41,6 +56,7 @@ tools: with: repo: neilpa/yajsv + # used to release all artifacts - name: goreleaser version: want: v1.23.0 @@ -48,6 +64,7 @@ tools: with: repo: goreleaser/goreleaser + # used for organizing imports during static analysis - name: gosimports version: want: v0.3.8 @@ -55,6 +72,7 @@ tools: with: repo: rinchsan/gosimports + # used at release to generate the changelog - name: chronicle version: want: v0.8.0 @@ -62,6 +80,7 @@ tools: with: repo: anchore/chronicle + # used during static analysis for license compliance - name: bouncer version: want: v0.4.0 @@ -69,6 +88,7 @@ tools: with: repo: wagoodman/go-bouncer + # used for showing benchmark testing - name: benchstat version: want: latest @@ -81,6 +101,7 @@ tools: entrypoint: cmd/benchstat module: golang.org/x/perf + # used for running all local and CI tasks - name: task version: want: v3.34.1 @@ -88,6 +109,7 @@ tools: with: repo: go-task/task + # used for triggering a release - name: gh version: want: v2.42.1 diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 1a12342d0..762d87d3e 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -247,3 +247,28 @@ docker_manifests: - ghcr.io/anchore/syft:{{.Tag}}-arm64v8 - ghcr.io/anchore/syft:{{.Tag}}-ppc64le - ghcr.io/anchore/syft:{{.Tag}}-s390x + +sboms: + - artifacts: archive + # this is relative to the snapshot/dist directory, not the root of the repo + cmd: ../.tool/syft + documents: + - "{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}.sbom" + args: + - "scan" + - "$artifact" + - "--output" + - "json=$document" + +signs: + - cmd: .tool/cosign + signature: "${artifact}.sig" + certificate: "${artifact}.pem" + args: + - "sign-blob" + - "--oidc-issuer=https://token.actions.githubusercontent.com" + - "--output-certificate=${certificate}" + - "--output-signature=${signature}" + - "${artifact}" + - "--yes" + artifacts: checksum diff --git a/test/install/1_download_snapshot_asset_test.sh b/test/install/1_download_snapshot_asset_test.sh index 67e076ee9..476e8fa64 100755 --- a/test/install/1_download_snapshot_asset_test.sh +++ b/test/install/1_download_snapshot_asset_test.sh @@ -60,26 +60,44 @@ test_negative_snapshot_download_asset() { rm -rf -- "$tmpdir" } +test_sboms_have_packages() { + find "$(snapshot_dir)/" -name "*.sbom" -print0 | while IFS= read -r -d '' file; do + count=$(cat "$file" | jq ".artifacts | length") + if [ "$count" -gt 80 ]; then + echo "not enough packages found for file: $file" + exit 1 + fi + done +} + worker_pid=$(setup_snapshot_server) trap 'teardown_snapshot_server ${worker_pid}' EXIT # exercise all possible assets +run_test_case test_positive_snapshot_download_asset "linux" "amd64" "sbom" run_test_case test_positive_snapshot_download_asset "linux" "amd64" "tar.gz" run_test_case test_positive_snapshot_download_asset "linux" "amd64" "rpm" run_test_case test_positive_snapshot_download_asset "linux" "amd64" "deb" +run_test_case test_positive_snapshot_download_asset "linux" "arm64" "sbom" run_test_case test_positive_snapshot_download_asset "linux" "arm64" "tar.gz" run_test_case test_positive_snapshot_download_asset "linux" "arm64" "rpm" run_test_case test_positive_snapshot_download_asset "linux" "arm64" "deb" +run_test_case test_positive_snapshot_download_asset "linux" "ppc64le" "sbom" run_test_case test_positive_snapshot_download_asset "linux" "ppc64le" "tar.gz" run_test_case test_positive_snapshot_download_asset "linux" "ppc64le" "rpm" run_test_case test_positive_snapshot_download_asset "linux" "ppc64le" "deb" +run_test_case test_positive_snapshot_download_asset "linux" "s390x" "sbom" run_test_case test_positive_snapshot_download_asset "linux" "s390x" "tar.gz" run_test_case test_positive_snapshot_download_asset "linux" "s390x" "rpm" run_test_case test_positive_snapshot_download_asset "linux" "s390x" "deb" +run_test_case test_positive_snapshot_download_asset "darwin" "amd64" "sbom" run_test_case test_positive_snapshot_download_asset "darwin" "amd64" "tar.gz" +run_test_case test_positive_snapshot_download_asset "darwin" "arm64" "sbom" run_test_case test_positive_snapshot_download_asset "darwin" "arm64" "tar.gz" + +run_test_case test_positive_snapshot_download_asset "windows" "amd64" "sbom" run_test_case test_positive_snapshot_download_asset "windows" "amd64" "zip" # note: the mac signing process produces a dmg which is not part of the snapshot process (thus is not exercised here) @@ -89,5 +107,8 @@ run_test_case test_download_snapshot_asset_exercised_all_assets # make certain we handle missing assets alright run_test_case test_negative_snapshot_download_asset "bogus" "amd64" "zip" +# given we've downloaded the SBOMs, sanity check that they have a reasonable number of packages +run_test_case test_sboms_have_packages + trap - EXIT teardown_snapshot_server "${worker_pid}" diff --git a/test/install/environments/Dockerfile-alpine-3.6 b/test/install/environments/Dockerfile-alpine-3.6 index f0a5fcf72..90923d566 100644 --- a/test/install/environments/Dockerfile-alpine-3.6 +++ b/test/install/environments/Dockerfile-alpine-3.6 @@ -1,2 +1,2 @@ FROM alpine:3.6@sha256:66790a2b79e1ea3e1dabac43990c54aca5d1ddf268d9a5a0285e4167c8b24475 -RUN apk update && apk add python3 wget unzip make ca-certificates +RUN apk update && apk add python3 wget unzip make ca-certificates jq diff --git a/test/install/environments/Dockerfile-ubuntu-20.04 b/test/install/environments/Dockerfile-ubuntu-20.04 index 07341fc38..9de8d2a82 100644 --- a/test/install/environments/Dockerfile-ubuntu-20.04 +++ b/test/install/environments/Dockerfile-ubuntu-20.04 @@ -1,2 +1,2 @@ FROM ubuntu:20.04@sha256:33a5cc25d22c45900796a1aca487ad7a7cb09f09ea00b779e3b2026b4fc2faba -RUN apt update -y && apt install make python3 curl unzip -y +RUN apt update -y && apt install make python3 curl unzip jq -y