From 0ffd7f6087e9da8c158fd5eaaa75b8b01b299447 Mon Sep 17 00:00:00 2001 From: Brend Smits Date: Fri, 18 Feb 2022 10:12:41 +0100 Subject: [PATCH] Create SBOM using Syft (#134) All container images and binaries now ship with a software bill of material in spdx-json format. The SBOMs for the binaries are attached to the GitHub Releases. The SBOMs for each container image tag are attached as attestations. Each SBOM is signed and can be verified using the cosign.pub key. This commit also changes the provenance extension from .json to .att (Attestation) Closes #61 #128 --- .github/workflows/ci.yaml | 74 ++++++++++++++++++++++++++++----------- .goreleaser.draft.yml | 20 +++++++++++ .goreleaser.yml | 20 +++++++++++ 3 files changed, 94 insertions(+), 20 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 1251e17d..0efad672 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -83,6 +83,9 @@ jobs: with: cosign-release: 'v1.5.1' + - name: Install Syft + uses: anchore/sbom-action/download-syft@v0.6.0 + - name: Checkout uses: actions/checkout@v2.4.0 with: @@ -141,6 +144,53 @@ jobs: if: ${{ always() }} run: rm -f cosign.key + sbom: + name: sbom + needs: [release] + if: startsWith(github.ref, 'refs/tags/') + runs-on: ubuntu-20.04 + env: + TAGS: "${{ needs.release.outputs.container_tags }}" + + strategy: + matrix: + repo: ${{ fromJSON(needs.release.outputs.container_repos) }} + + steps: + - name: Install cosign + uses: sigstore/cosign-installer@v2.0.0 + with: + cosign-release: 'v1.5.1' + + - name: Install Syft + uses: anchore/sbom-action/download-syft@v0.6.0 + + - name: Login to Container registries + run: | + echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u philipssoftware --password-stdin + echo "${{ secrets.GITHUB_TOKEN }}" | docker login -u ${{ github.actor }} --password-stdin ghcr.io + + - name: Attach SBOM + env: + COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} + run: | + echo '${{ secrets.COSIGN_PUBLIC_KEY }}' > cosign.pub + echo '${{ secrets.COSIGN_PRIVATE_KEY }}' > cosign.key + IFS=, + for t in ${TAGS}; do + cosign verify --key cosign.pub ${{ matrix.repo }}:${t} + syft ${{ matrix.repo }}:${t} -o spdx-json > sbom-spdx.json + cosign attest --predicate sbom-spdx.json --type spdx --key cosign.key ${{ matrix.repo }}:${t} + cosign verify-attestation -o verified-sbom-spdx.json --key cosign.pub ${{ matrix.repo }}:${t} + done + + - name: Clean up & Logout from Container registries + if: ${{ always() }} + run: | + docker logout + docker logout ghcr.io + rm -f cosign.key + container-provenance: name: container-provenance needs: [release] @@ -158,17 +208,17 @@ jobs: cosign-release: 'v1.5.1' - name: Generate provenance for ${{ matrix.repo }} - uses: philips-labs/slsa-provenance-action@v0.7.0 + uses: philips-labs/slsa-provenance-action@v0.8.1-draft with: command: generate subcommand: container - arguments: --repository ${{ matrix.repo }} --digest ${{ needs.release.outputs.container_digest }} --tags ${{ needs.release.outputs.container_tags }} + arguments: --repository ${{ matrix.repo }} --output-path provenance.att --digest ${{ needs.release.outputs.container_digest }} --tags ${{ needs.release.outputs.container_tags }} env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - name: Get slsa-provenance predicate run: | - cat provenance.json | jq .predicate > provenance-predicate.json + cat provenance.att | jq .predicate > provenance-predicate.att - name: Login to Container registries if: startsWith(github.ref, 'refs/tags/') @@ -179,7 +229,7 @@ jobs: - name: Attach provenance to image run: | echo '${{ secrets.COSIGN_PRIVATE_KEY }}' > cosign.key - cosign attest --predicate provenance-predicate.json --type slsaprovenance --key cosign.key ${{ matrix.repo }}@${{ needs.release.outputs.container_digest }} + cosign attest --predicate provenance-predicate.att --type slsaprovenance --key cosign.key ${{ matrix.repo }}@${{ needs.release.outputs.container_digest }} env: COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} @@ -194,19 +244,3 @@ jobs: docker logout docker logout ghcr.io rm -f cosign.key - - provenance: - name: provenance - needs: [release] - if: startsWith(github.ref, 'refs/tags/') - runs-on: ubuntu-20.04 - - steps: - - name: Generate provenance for Release - uses: philips-labs/slsa-provenance-action@v0.7.0 - with: - command: generate - subcommand: github-release - arguments: --artifact-path release-assets --output-path provenance.json --tag-name ${{ github.ref_name }} - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.goreleaser.draft.yml b/.goreleaser.draft.yml index 9c2c120f..65e95b99 100644 --- a/.goreleaser.draft.yml +++ b/.goreleaser.draft.yml @@ -36,6 +36,14 @@ archives: - goos: windows format: zip +sboms: + - id: archive-sbom + cmd: syft + args: ["${artifact}", "--file", "${artifact}.sbom.json", "--output", "spdx-json"] + documents: + - "${artifact}.sbom.json" + artifacts: archive + checksum: name_template: 'checksums.txt' @@ -102,6 +110,18 @@ signs: - '--output-certificate=${certificate}' - '--output-signature=${signature}' - '${artifact}' + - id: sboms + cmd: cosign + stdin: '{{ .Env.COSIGN_PASSWORD }}' + output: true + artifacts: sbom + args: + - sign-blob + - --key + - cosign.key + - '--output-certificate=${certificate}' + - '--output-signature=${signature}' + - '${artifact}' docker_signs: - cmd: cosign diff --git a/.goreleaser.yml b/.goreleaser.yml index 6ecc946a..67562de3 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -36,6 +36,14 @@ archives: - goos: windows format: zip +sboms: + - id: archive-sbom + cmd: syft + args: ["${artifact}", "--file", "${artifact}.sbom.json", "--output", "spdx-json"] + documents: + - "${artifact}.sbom.json" + artifacts: archive + checksum: name_template: 'checksums.txt' @@ -102,6 +110,18 @@ signs: - '--output-certificate=${certificate}' - '--output-signature=${signature}' - '${artifact}' + - id: sboms + cmd: cosign + stdin: '{{ .Env.COSIGN_PASSWORD }}' + output: true + artifacts: sbom + args: + - sign-blob + - --key + - cosign.key + - '--output-certificate=${certificate}' + - '--output-signature=${signature}' + - '${artifact}' docker_signs: - cmd: cosign