From 3e9884e487ebb37f31c6b831fe9b28cd867330a8 Mon Sep 17 00:00:00 2001 From: David Ahmann Date: Wed, 18 Feb 2026 09:21:01 -0500 Subject: [PATCH] Fail closed chain loading and harden CI/release pinning --- .github/workflows/main.yml | 4 ++-- .github/workflows/release.yml | 11 ++++++++++- cmd/proof/artifacts.go | 2 +- cmd/proof/more_branches_test.go | 7 +++++++ cmd/proof/verify_cmd_test.go | 5 +++++ 5 files changed, 25 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1588984..8e4217b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,11 +17,11 @@ jobs: - run: go vet ./... - name: gosec run: | - go install github.com/securego/gosec/v2/cmd/gosec@latest + go install github.com/securego/gosec/v2/cmd/gosec@v2.23.0 gosec ./... - name: govulncheck run: | - go install golang.org/x/vuln/cmd/govulncheck@latest + go install golang.org/x/vuln/cmd/govulncheck@v1.1.4 govulncheck ./... test: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1bd5388..5a74ed3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -22,7 +22,7 @@ jobs: go-version-file: go.mod - uses: goreleaser/goreleaser-action@v6 with: - version: latest + version: v2.13.3 args: release --clean env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -42,6 +42,15 @@ jobs: cosign sign-blob --yes --output-signature dist/checksums.txt.sig --output-certificate dist/checksums.txt.pem dist/checksums.txt - name: Verify signed checksums run: ./scripts/verify_release_artifacts.sh dist + - name: Upload checksum signature assets to release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release upload "${{ github.ref_name }}" \ + dist/checksums.txt.sig \ + dist/checksums.txt.pem \ + --repo "${{ github.repository }}" \ + --clobber - name: Generate build provenance uses: actions/attest-build-provenance@v2 with: diff --git a/cmd/proof/artifacts.go b/cmd/proof/artifacts.go index 18408d5..efdc656 100644 --- a/cmd/proof/artifacts.go +++ b/cmd/proof/artifacts.go @@ -108,7 +108,7 @@ func loadChain(path string) (*proof.Chain, error) { } r, err := loadRecord(f) if err != nil { - continue + return nil, fmt.Errorf("parse %s: %w", base, err) } c.Records = append(c.Records, *r) c.RecordCount = len(c.Records) diff --git a/cmd/proof/more_branches_test.go b/cmd/proof/more_branches_test.go index bb99e4d..d3761cf 100644 --- a/cmd/proof/more_branches_test.go +++ b/cmd/proof/more_branches_test.go @@ -52,6 +52,13 @@ func TestLoadChainFallbackAndJSONLError(t *testing.T) { require.Error(t, err) } +func TestLoadChainMalformedJSONRecordFails(t *testing.T) { + dir := t.TempDir() + testutil.WriteFile(t, filepath.Join(dir, "bad.json"), []byte("{not-json")) + _, err := loadChain(dir) + require.Error(t, err) +} + func TestBundleAndGaitHelperErrors(t *testing.T) { dir := t.TempDir() testutil.WriteFile(t, filepath.Join(dir, "manifest.json"), []byte(`{"files":[{"path":"a.txt","sha256":"sha256:abcd"}]}`)) diff --git a/cmd/proof/verify_cmd_test.go b/cmd/proof/verify_cmd_test.go index 7eb654f..091f2fc 100644 --- a/cmd/proof/verify_cmd_test.go +++ b/cmd/proof/verify_cmd_test.go @@ -64,6 +64,11 @@ func TestVerifyCommandErrorPaths(t *testing.T) { require.NoError(t, proof.WriteRecord(p, r)) _, err = runCLIForTest(t, []string{"verify", "--signatures", p}) require.Error(t, err) + + chainDir := t.TempDir() + testutil.WriteFile(t, filepath.Join(chainDir, "bad.json"), []byte("{not-json")) + _, err = runCLIForTest(t, []string{"verify", chainDir}) + require.Error(t, err) } func TestVerifyBundleWithManifestSignature(t *testing.T) {