diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index cf68f2af..fae44ffb 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,4 +1,5 @@ -name: "Release" +name: release + on: workflow_dispatch: inputs: @@ -92,6 +93,8 @@ jobs: permissions: contents: write packages: write + outputs: + hashes: ${{ steps.binary.outputs.hashes }} steps: - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v2.5.0 with: @@ -136,3 +139,32 @@ jobs: with: name: artifacts path: dist/**/* + + - name: Generate binary hashes + id: binary + run: | + set -euo pipefail + + # find the checksum file in the dist directory + checksum_file=$(find dist -name '*_checksums.txt') + # get the base64 encoded checksums + hashes=$(cat "$checksum_file" | base64 -w0) + # set the output + echo "hashes=$hashes" >> "$GITHUB_OUTPUT" + echo $hashes + + binary-provenance: + needs: [release] + permissions: + actions: read # To read the workflow path. + id-token: write # To sign the provenance. + contents: write # To add assets to a release. + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.9.0 + with: + base64-subjects: "${{ needs.release.outputs.hashes }}" + upload-assets: true # upload to a new release + upload-tag-name: "${{ github.event.inputs.version }}" + + + + diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 9e156b3f..fcc79073 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -16,10 +16,17 @@ builds: goarch: - amd64 - arm64 - - ppc64le - - s390x # set the modified timestamp on the output binary to the git timestamp to ensure a reproducible build mod_timestamp: &build-timestamp '{{ .CommitTimestamp }}' + flags: + # trimpath is for reproducible builds + # remove all file system paths from the resulting executable. + # Instead of absolute file system paths, the recorded file names + # will begin with either "go" (for the standard library), + # or a module path@version (when using modules), + # or a plain import path (when using GOPATH). + - -trimpath + - -tags=netgo ldflags: &build-ldflags | -w -s @@ -37,6 +44,15 @@ builds: goarch: - amd64 - arm64 + flags: + # trimpath is for reproducible builds + # remove all file system paths from the resulting executable. + # Instead of absolute file system paths, the recorded file names + # will begin with either "go" (for the standard library), + # or a module path@version (when using modules), + # or a plain import path (when using GOPATH). + - -trimpath + - -tags=netgo mod_timestamp: *build-timestamp ldflags: *build-ldflags @@ -47,6 +63,16 @@ builds: - windows goarch: - amd64 + - arm64 + flags: + # trimpath is for reproducible builds + # remove all file system paths from the resulting executable. + # Instead of absolute file system paths, the recorded file names + # will begin with either "go" (for the standard library), + # or a module path@version (when using modules), + # or a plain import path (when using GOPATH). + - -trimpath + - -tags=netgo mod_timestamp: *build-timestamp ldflags: *build-ldflags @@ -115,21 +141,6 @@ dockers: - "--build-arg=VCS_REF={{.FullCommit}}" - "--build-arg=VCS_URL={{.GitURL}}" - - image_templates: - - noqcks/xeol:debug-s390x - - noqcks/xeol:{{.Tag}}-debug-s390x - - ghcr.io/noqcks/xeol:debug-s390x - - ghcr.io/noqcks/xeol:{{.Tag}}-debug-s390x - goarch: s390x - dockerfile: Dockerfile.debug - use: buildx - build_flag_templates: - - "--platform=linux/s390x" - - "--build-arg=BUILD_DATE={{.Date}}" - - "--build-arg=BUILD_VERSION={{.Version}}" - - "--build-arg=VCS_REF={{.FullCommit}}" - - "--build-arg=VCS_URL={{.GitURL}}" - - image_templates: - noqcks/xeol:latest - noqcks/xeol:{{.Tag}} @@ -158,52 +169,32 @@ dockers: - "--build-arg=VCS_REF={{.FullCommit}}" - "--build-arg=VCS_URL={{.GitURL}}" - - image_templates: - - noqcks/xeol:{{.Tag}}-s390x - - ghcr.io/noqcks/xeol:{{.Tag}}-s390x - goarch: s390x - dockerfile: Dockerfile - use: buildx - build_flag_templates: - - "--platform=linux/s390x" - - "--build-arg=BUILD_DATE={{.Date}}" - - "--build-arg=BUILD_VERSION={{.Version}}" - - "--build-arg=VCS_REF={{.FullCommit}}" - - "--build-arg=VCS_URL={{.GitURL}}" - - docker_manifests: - name_template: noqcks/xeol:latest image_templates: - noqcks/xeol:{{.Tag}} - noqcks/xeol:{{.Tag}}-arm64v8 - - noqcks/xeol:{{.Tag}}-s390x - name_template: noqcks/xeol:debug - noqcks/xeol:{{.Tag}}-debug - noqcks/xeol:{{.Tag}}-debug-arm64v8 - - noqcks/xeol:{{.Tag}}-debug-s390x - name_template: noqcks/xeol:{{.Tag}} image_templates: - noqcks/xeol:{{.Tag}} - noqcks/xeol:{{.Tag}}-arm64v8 - - noqcks/xeol:{{.Tag}}-s390x - name_template: ghcr.io/noqcks/xeol:latest image_templates: - ghcr.io/noqcks/xeol:{{.Tag}} - ghcr.io/noqcks/xeol:{{.Tag}}-arm64v8 - - ghcr.io/noqcks/xeol:{{.Tag}}-s390x - name_template: ghcr.io/noqcks/xeol:debug image_templates: - ghcr.io/noqcks/xeol:{{.Tag}}-debug - ghcr.io/noqcks/xeol:{{.Tag}}-debug-arm64v8 - - ghcr.io/noqcks/xeol:{{.Tag}}-debug-s390x - name_template: ghcr.io/noqcks/xeol:{{.Tag}} image_templates: - ghcr.io/noqcks/xeol:{{.Tag}} - ghcr.io/noqcks/xeol:{{.Tag}}-arm64v8 - - ghcr.io/noqcks/xeol:{{.Tag}}-s390x diff --git a/README.md b/README.md index 3fe9c544..91842b13 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ [![GitHub release](https://img.shields.io/github/release/xeol-io/xeol.svg)](https://github.com/xeol-io/xeol/releases/latest) [![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/xeol-io/xeol.svg)](https://github.com/xeol-io/xeol) [![License: Apache-2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/xeol-io/xeol/blob/main/LICENSE) +[![SLSA 3](https://slsa.dev/images/gh-badge-level3.svg)](https://slsa.dev) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/xeol-io/xeol/badge)](https://api.securityscorecards.dev/projects/github.com/xeol-io/xeol) [![Github All Releases](https://img.shields.io/github/downloads/xeol-io/xeol/total.svg)](https://img.shields.io/github/downloads/xeol-io/xeol/total.svg) [![](https://dcbadge.vercel.app/api/server/23ucxwsb?style=flat)](https://discord.gg/23ucxwsb) @@ -42,6 +43,24 @@ brew install xeol If you're using GitHub Actions, you can simply use the [Xeol GitHub action](https://github.com/marketplace/actions/xeol-end-of-life-eol-scan) to run EOL scans on your code or container images during your CI workflows. +### Verifying SLSA provenance for downloaded releases + +We generate SLSA provenance for all Xeol releases starting with v0.9.5. You can verify the provenance for the release binaries like so: +1. Install the [slsa-framework/slsa-verifier#installation](https://github.com/slsa-framework/slsa-verifier#installation) tool +2. Download the signature file `attestation.intoto.jsonl` from a Xeol release +3. Download the Xeol release binary you want to verify +4. Run `slsa-verifier verify-artifact --provenance-path multiple.intoto.jsonl --source-uri=github.com/xeol-io/xeol` + +You should see something like this is the release binary is verified: +``` +➜ ~ slsa-verifier verify-artifact --provenance-path multiple.intoto.jsonl xeol_0.9.5_darwin_amd64.tar.gz --source-uri=github.com/xeol-io/xeol +Verified signature against tlog entry index 44906341 at URL: https://rekor.sigstore.dev/api/v1/log/entries/24296fb24b8ad77a658e74e86e03e7aedcca39eebddebf59310b4d9c463b037951109186d73a5681 +Verified build using builder "https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@refs/tags/v1.9.0" at commit fdc6f5efca3f7277aacf25ef42f502355398f512 +Verifying artifact xeol_0.9.5_darwin_amd64.tar.gz: PASSED + +PASSED: Verified SLSA provenance +``` + ## Getting started [Install the binary](#installation), and make sure that `xeol` is available in your path. To scan for EOL packages in an image: diff --git a/test/install/1_download_snapshot_asset_test.sh b/test/install/1_download_snapshot_asset_test.sh index b7c82ba0..f44c7911 100755 --- a/test/install/1_download_snapshot_asset_test.sh +++ b/test/install/1_download_snapshot_asset_test.sh @@ -71,16 +71,10 @@ run_test_case test_positive_snapshot_download_asset "linux" "amd64" "deb" 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" "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 "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 "darwin" "amd64" "tar.gz" run_test_case test_positive_snapshot_download_asset "darwin" "arm64" "tar.gz" 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) +run_test_case test_positive_snapshot_download_asset "windows" "arm64" "zip" # let's make certain we covered all assets that were expected run_test_case test_download_snapshot_asset_exercised_all_assets diff --git a/test/install/3_install_asset_test.sh b/test/install/3_install_asset_test.sh index d2699232..f3fec7b5 100755 --- a/test/install/3_install_asset_test.sh +++ b/test/install/3_install_asset_test.sh @@ -82,11 +82,10 @@ trap 'teardown_snapshot_server ${worker_pid}' EXIT # exercise all possible archive assets (not rpm/deb/dmg) against a snapshot build run_test_case test_positive_snapshot_install_asset "linux" "amd64" "tar.gz" run_test_case test_positive_snapshot_install_asset "linux" "arm64" "tar.gz" -run_test_case test_positive_snapshot_install_asset "linux" "s390x" "tar.gz" -run_test_case test_positive_snapshot_install_asset "linux" "ppc64le" "tar.gz" run_test_case test_positive_snapshot_install_asset "darwin" "amd64" "tar.gz" run_test_case test_positive_snapshot_install_asset "darwin" "arm64" "tar.gz" run_test_case test_positive_snapshot_install_asset "windows" "amd64" "zip" +run_test_case test_positive_snapshot_install_asset "windows" "arm64" "zip" # let's make certain we covered all assets that were expected run_test_case test_install_asset_exercised_all_archive_assets