diff --git a/.clusterfuzzlite/Dockerfile b/.clusterfuzzlite/Dockerfile index 2a67e0c..0ff21a1 100644 --- a/.clusterfuzzlite/Dockerfile +++ b/.clusterfuzzlite/Dockerfile @@ -1,7 +1,9 @@ # ClusterFuzzLite build image — OpenSSF Scorecard detects fuzzing via this file. # Uses the OSS-Fuzz JavaScript base builder (Jazzer.js), which provides # `compile_javascript_fuzzer`. See build.sh for the fuzz targets. -FROM gcr.io/oss-fuzz-base/base-builder-javascript +# Base pinned by digest (Scorecard Pinned-Dependencies). OSS-Fuzz rolls this +# image, so bump the digest periodically if the weekly fuzz build breaks. +FROM gcr.io/oss-fuzz-base/base-builder-javascript@sha256:717f88cd72ee85ab295debf1272eed85590621d6ba9d70d6c59133a61f3f3acf COPY . $SRC/truecopy WORKDIR $SRC/truecopy COPY .clusterfuzzlite/build.sh $SRC/build.sh diff --git a/.clusterfuzzlite/build.sh b/.clusterfuzzlite/build.sh index 21ff40e..c58a6f8 100755 --- a/.clusterfuzzlite/build.sh +++ b/.clusterfuzzlite/build.sh @@ -7,7 +7,9 @@ # `vetted`, and the poison scanner always returns a well-formed verdict on any # malformed skill. cd "$SRC/truecopy" -npm install --no-audit --no-fund +# npm ci verifies every integrity hash in the committed lockfile +# (Scorecard Pinned-Dependencies); Jazzer comes in as the locked devDependency. +npm ci --no-audit --no-fund for target in canonical_json gate_tools scan_skill; do compile_javascript_fuzzer truecopy "fuzz/${target}.fuzz.js" --sync diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml index 53257b6..11eb367 100644 --- a/.github/workflows/auto-release.yml +++ b/.github/workflows/auto-release.yml @@ -30,6 +30,8 @@ jobs: permissions: contents: write # push the tag + create the GitHub release actions: write # dispatch publish.yml + id-token: write # keyless Sigstore signing (attest-build-provenance) + attestations: write # persist the attestation in GitHub's store steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: @@ -148,6 +150,34 @@ jobs: --title "$TAG" \ --notes-file release-notes.md + - name: Build npm tarball (release artifact) + if: steps.gate.outputs.skip != 'true' && steps.bumped.outputs.skip != 'true' + id: pack + run: | + set -euo pipefail + tarball=$(npm pack --silent) + echo "tarball=${tarball}" >> "$GITHUB_OUTPUT" + sha256sum "$tarball" + + - name: Attest build provenance (keyless Sigstore) + if: steps.gate.outputs.skip != 'true' && steps.bumped.outputs.skip != 'true' + id: attest + uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4.1.1 + with: + subject-path: ${{ steps.pack.outputs.tarball }} + + - name: Upload tarball + provenance bundle to the release + if: steps.gate.outputs.skip != 'true' && steps.bumped.outputs.skip != 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAG: ${{ steps.version.outputs.tag }} + TARBALL: ${{ steps.pack.outputs.tarball }} + BUNDLE: ${{ steps.attest.outputs.bundle-path }} + run: | + set -euo pipefail + cp "$BUNDLE" "${TARBALL}.sigstore.json" + gh release upload "$TAG" --clobber "$TARBALL" "${TARBALL}.sigstore.json" + - name: Hand off to the OIDC publisher if: steps.gate.outputs.skip != 'true' && steps.bumped.outputs.skip != 'true' env: