From ac15644513d3182b160d5c445e35abf23addab40 Mon Sep 17 00:00:00 2001 From: Lucas Bickel <116588+hairmare@users.noreply.github.com> Date: Sun, 9 Jul 2023 22:51:05 +0200 Subject: [PATCH] feat(containers): generate and attest trivy SBOM (#52) Also introduces using new trivy convert command to reduce scanning overhead --- .github/workflows/release-container.yaml | 52 +++++++++++++++++++----- .github/workflows/schedule-trivy.yaml | 37 ++++++++++++----- README.md | 3 ++ 3 files changed, 70 insertions(+), 22 deletions(-) diff --git a/.github/workflows/release-container.yaml b/.github/workflows/release-container.yaml index 7f52939..9eca43e 100644 --- a/.github/workflows/release-container.yaml +++ b/.github/workflows/release-container.yaml @@ -122,19 +122,32 @@ jobs: env: DOCKER_CONTENT_TRUST: 1 - - name: Run Trivy vulnerability scanner (sarif) + - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@0.11.2 with: image-ref: '${{ inputs.image }}:${{ steps.meta.outputs.version }}' - format: 'sarif' + format: 'json' ignore-unfixed: true - output: 'trivy-results.sarif' + list-all-pkgs: true + output: 'trivy.json' + + - name: Convert trivy results to sarif + uses: aquasecurity/trivy-action@0.11.2 + with: + image-ref: trivy.json + scan-type: 'convert' + format: 'sarif' + # we don't actually limit them, but this gates the convert action + limit-severities-for-sarif: true + # empty makes it skip the --vuln-type arg + vuln-type: '' + output: 'trivy.sarif' - name: Upload Trivy scan results to GitHub Security tab uses: github/codeql-action/upload-sarif@v2 if: always() with: - sarif_file: 'trivy-results.sarif' + sarif_file: 'trivy.sarif' - name: Login to GitHub Container Registry uses: docker/login-action@v2 @@ -166,17 +179,34 @@ jobs: env: TAGS: ${{ steps.meta.outputs.tags }} - # see https://github.com/aquasecurity/trivy/issues/3243 for why we run it twice - # we create a vuln.jsn if we also plan on uploading it as attestation - - name: Run Trivy vulnerability scanner (cosign-vuln) + - name: Convert trivy results to CycloneDX uses: aquasecurity/trivy-action@0.11.2 + with: + image-ref: trivy.json + scan-type: 'convert' + format: 'cyclonedx' + # we don't actually limit them, but this gates the convert action + limit-severities-for-sarif: true + # empty makes it skip the --vuln-type arg + vuln-type: '' + output: 'trivy.cdx' + + - name: Attach an SBOM attestation to the signed image + run: cosign attest --yes --type cyclonedx --predicate trivy.cdx ${{ inputs.image }}@${{ steps.docker_push.outputs.digest }} if: github.event_name != 'pull_request' && startsWith(github.event.ref, 'refs/tags/v') + + - name: Convert trivy results to cosign-vuln + uses: aquasecurity/trivy-action@0.11.2 with: - image-ref: '${{ inputs.image }}:${{ steps.meta.outputs.version }}' + image-ref: trivy.json + scan-type: 'convert' format: 'cosign-vuln' - ignore-unfixed: true - output: 'vuln.json' + # we don't actually limit them, but this gates the convert action + limit-severities-for-sarif: true + # empty makes it skip the --vuln-type arg + vuln-type: '' + output: 'trivy.cosign.json' - name: Attach a security attestation to the signed image - run: cosign attest --yes --type vuln --predicate vuln.json ${{ inputs.image }}@${{ steps.docker_push.outputs.digest }} + run: cosign attest --yes --type vuln --predicate trivy.cosign.json ${{ inputs.image }}@${{ steps.docker_push.outputs.digest }} if: github.event_name != 'pull_request' && startsWith(github.event.ref, 'refs/tags/v') diff --git a/.github/workflows/schedule-trivy.yaml b/.github/workflows/schedule-trivy.yaml index b80befd..791b101 100644 --- a/.github/workflows/schedule-trivy.yaml +++ b/.github/workflows/schedule-trivy.yaml @@ -34,31 +34,46 @@ jobs: - name: Install Cosign uses: sigstore/cosign-installer@v3.1.1 - - name: Run Trivy vulnerability scanner (sarif) + - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@0.11.2 with: image-ref: ${{ inputs.image-ref }} timeout: ${{ inputs.timeout }} - format: 'sarif' + format: 'json' ignore-unfixed: true + list-all-pkgs: true scanners: 'vuln' - output: 'trivy-results.sarif' + output: 'trivy.json' + + - name: Convert trivy results to sarif + uses: aquasecurity/trivy-action@0.11.2 + with: + image-ref: trivy.json + scan-type: 'convert' + format: 'sarif' + # we don't actually limit them, but this gates the convert action + limit-severities-for-sarif: true + # empty makes it skip the --vuln-type arg + vuln-type: '' + output: 'trivy.sarif' - name: Upload Trivy scan results to GitHub Security tab uses: github/codeql-action/upload-sarif@v2 if: always() with: - sarif_file: 'trivy-results.sarif' + sarif_file: 'trivy.sarif' - # see https://github.com/aquasecurity/trivy/issues/3243 for why we run it twice - # we create a vuln.jsn if we also plan on uploading it as attestation - - name: Run Trivy vulnerability scanner (cosign-vuln) + - name: Convert trivy results to cosign-vuln uses: aquasecurity/trivy-action@0.11.2 with: - image-ref: 'ghcr.io/radiorabe/ubi9-minimal:${{ steps.meta.outputs.version }}' + image-ref: trivy.json + scan-type: 'convert' format: 'cosign-vuln' - ignore-unfixed: true - output: 'vuln.json' + # we don't actually limit them, but this gates the convert action + limit-severities-for-sarif: true + # empty makes it skip the --vuln-type arg + vuln-type: '' + output: 'trivy.cosign.json' - name: Login to GitHub Container Registry uses: docker/login-action@v2 @@ -68,4 +83,4 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Attach a security attestation to the signed image - run: cosign attest --yes --type vuln --predicate vuln.json ${{ inputs.image-ref }} + run: cosign attest --yes --type vuln --predicate trivy.cosign.json ${{ inputs.image-ref }} diff --git a/README.md b/README.md index b2aec3b..c5a6879 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,9 @@ jobs: 8. Pass `--base-image-only` to cosign if you are copying binaries from a source image that isn't signed with cosign. +As a last step, it is recommended to add `trivy.*` to both your `.gitignore` +and `.dockerignore` files so trivy can't interfere with multi-stage builds. + #### Container: Schedule To scan the latest container image with trivy at regular intervals, create this `.github/workflows/schedule.yaml`: