From 0ccacffed804d85da3f938a1b78c12831935f992 Mon Sep 17 00:00:00 2001 From: Datong Sun Date: Mon, 2 Dec 2024 21:04:55 +0800 Subject: [PATCH] feat(security-actions/scan-docker-image): support `trivy_db_cache` as alternate (#184) * feat(security-actions/scan-docker-image): support `trivy_db_cache` as input which allows caching the Trivy DB to get around rate limiting issues * chore(ci): disable skipping cis scan * feat(security-actions/scan-docker-image): bump trivy 0.57.1 to use updated mirror for `trivy-db` and `trivy-java-db` * docs: update example on using trivy internal cache mirror and access permissions --------- Co-authored-by: saisatishkarra --- .github/workflows/docker-image-scan.yml | 6 +- security-actions/scan-docker-image/README.md | 28 ++++++- security-actions/scan-docker-image/action.yml | 74 +++++++++++++++++-- 3 files changed, 94 insertions(+), 14 deletions(-) diff --git a/.github/workflows/docker-image-scan.yml b/.github/workflows/docker-image-scan.yml index 11d9b0bd..1b054a04 100644 --- a/.github/workflows/docker-image-scan.yml +++ b/.github/workflows/docker-image-scan.yml @@ -63,7 +63,9 @@ jobs: with: asset_prefix: kong-gateway-dev-linux-amd64 image: ${{env.IMAGE}}@${{ steps.image_manifest_metadata.outputs.amd64_sha }} - skip_cis_scan: true + skip_cis_scan: false + trivy_db_cache: Kong/trivy-db-mirror@master + trivy_db_cache_token: ${{ secrets.PAT }} - name: Scan ARM64 Image digest if: steps.image_manifest_metadata.outputs.manifest_list_exists == 'true' && steps.image_manifest_metadata.outputs.arm64_sha != '' @@ -73,7 +75,7 @@ jobs: asset_prefix: test.kong-gateway-dev-linux-arm64 image: ${{env.IMAGE}}@${{ steps.image_manifest_metadata.outputs.arm64_sha }} upload-sbom-release-assets: true - skip_cis_scan: true + skip_cis_scan: false test-download-sbom: if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }} diff --git a/security-actions/scan-docker-image/README.md b/security-actions/scan-docker-image/README.md index 80945afb..8cd1abb6 100644 --- a/security-actions/scan-docker-image/README.md +++ b/security-actions/scan-docker-image/README.md @@ -5,8 +5,8 @@ - [Scan Docker Image](./action.yml) is a action for container SCA image scanning and CIS benchmarks. The action produces an SBOM, CVE, and CIS benchmark scanning and reports for a given image. - Tools used: - [syft](https://github.com/anchore/syft) generates a Software Bill of Materials (SBOM) - - [grype](https://github.com/anchore/grype) vulnerability scanner for container images - - [trivy](https://github.com/aquasecurity/trivy) compliance scanner for docker-cis + - [grype](https://github.com/anchore/grype) vulnerability scanner for CVEs in container images + - [trivy](https://github.com/aquasecurity/trivy) compliance scanner for docker-cis benchmarks ### Scan Docker Image @@ -16,7 +16,7 @@ - Leverages the syft action to generate an SBOM based on input parameters and uploads it as a github workflow artifact -#### Vulnerability Scanning Working +#### Grype Vulnerability Scanning Working - Action performs a scan of the sbom based on a user provided grype configuration: - First iteration: @@ -32,6 +32,14 @@ - Additional grype ignore rules and matches are applied and suppressed in console log - Helps developers better prioritize cve's by suppressing false positives and bypass cve's during hot fixes using break glass strategy +#### Trivy Compliance Scanner Working +- By default, trivy scans the docker image against `docker-cis-1.6.0` benchmarks +- Trivy compliance scanner leverages `trivy-db` for CIS benchmarks + - By default, it downloads the latest DB from upstream `mirror.gcr.io/aquasec/trivy-db` pull through cache mirror + - __[_OPTIONAL_]__ For more availability of `trivy-db` (**i.e bypass rate limiting issues**), refer [how to access cached trivy db for running CIS benchmarks](https://github.com/Kong/trivy-db-mirror?tab=readme-ov-file#how-to-consume-cached-trivy-db-when-invoking-public-shared-actions) +- Trivy complaince scanner **DOESNOT** scan for any vulnerabilities in the container image. This process is handled by [grype](https://github.com/anchore/grype) + + #### Input specification - Global parameters can be used for enforcement by centralized team across all repositories. @@ -70,10 +78,13 @@ permissions: #### User provided input parameters -- Inputs **image** is mandatory +- Input `image` is **MANDATORY** - OCI tar balls / Docker archives (OCI compatible) are considered as input type **Image** +- Input `trivy_db_cache` and `trivy_db_cache_token` are **OPTIONAL** + - Refer [how access cached trivy db for CIS benchmarks](https://github.com/Kong/trivy-db-mirror?tab=readme-ov-file#how-to-consume-cached-trivy-db-when-invoking-public-shared-actions) + ```yaml asset_prefix: description: 'prefix for generated scan artifacts' @@ -116,6 +127,12 @@ permissions: options: - 'true' - 'false' + trivy_db_cache: + description: 'GitHub repository containing Trivy DB cache (format: owner/repo@ref). Database should be named `db.tar.gz` on the default branch.' + required: false + trivy_db_cache_token: + description: 'Token for accessing `trivy_db_cache`.' + required: false ``` #### Output specification @@ -238,6 +255,7 @@ jobs: if: steps.image_manifest_metadata.outputs.amd64_sha != '' uses: Kong/public-shared-actions/security-actions/scan-docker-image@main with: + # Leverages trivy DB config from upstream mirror by default asset_prefix: kong-gateway-dev-linux-amd64 image: ${{env.IMAGE}}@${{ steps.image_manifest_metadata.outputs.amd64_sha }} @@ -248,4 +266,6 @@ jobs: with: asset_prefix: kong-gateway-dev-linux-arm64 image: ${{env.IMAGE}}@${{ steps.image_manifest_metadata.outputs.arm64_sha }} + trivy_db_cache: + trivy_db_cache_token: ${{ secrets.PAT }} ``` \ No newline at end of file diff --git a/security-actions/scan-docker-image/action.yml b/security-actions/scan-docker-image/action.yml index adbb7109..9fa52114 100644 --- a/security-actions/scan-docker-image/action.yml +++ b/security-actions/scan-docker-image/action.yml @@ -67,6 +67,12 @@ inputs: options: - 'true' - 'false' + trivy_db_cache: + description: 'GitHub repository containing Trivy DB cache (format: owner/repo@ref). Database should be named `db.tar.gz` on the default branch.' + required: false + trivy_db_cache_token: + description: 'Token for accessing `trivy_db_cache`.' + required: false outputs: cis-json-report: @@ -302,13 +308,60 @@ runs: with: files: "${{ steps.meta.outputs.scan_image }}" + - name: Parse Trivy DB cache input + if: inputs.trivy_db_cache != '' + shell: bash + id: parse_cache + run: | + REPO=$(echo "${{ inputs.trivy_db_cache }}" | cut -d'@' -f1) + REF=$(echo "${{ inputs.trivy_db_cache }}" | cut -d'@' -f2) + echo "repository=${REPO}" >> $GITHUB_OUTPUT + echo "ref=${REF}" >> $GITHUB_OUTPUT + + # Issue: https://github.com/aquasecurity/trivy/issues/7938 + # Discussion: https://github.com/aquasecurity/trivy/discussions/7668 + # Fix: Refer https://github.com/aquasecurity/trivy/discussions/7951 usign mirror.gcr.io + - name: Install Trivy + shell: bash + run: | + curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin v0.57.1 + + - name: Checkout Trivy DB cache + if: inputs.trivy_db_cache != '' + uses: actions/checkout@v4 + with: + repository: ${{ steps.parse_cache.outputs.repository }} + ref: ${{ steps.parse_cache.outputs.ref }} + path: trivy-db-cache + token: ${{ inputs.trivy_db_cache_token }} + + - name: Setup Trivy DB from cache + if: inputs.trivy_db_cache != '' + shell: bash + run: | + # Create Trivy cache directory + mkdir -p ~/.cache/trivy/db + + # Extract the DB + cd trivy-db-cache + tar -xvf db.tar.gz -C ~/.cache/trivy/db + cd .. + rm -rf trivy-db-cache + + # Issue: https://github.com/aquasecurity/trivy/issues/7938 + # Fix: Refer https://github.com/aquasecurity/trivy/discussions/7951 usign mirror.gcr.io - name: Generate docker-cis JSON report - uses: docker://aquasec/trivy:0.55.2 if: ${{ inputs.skip_cis_scan != 'true' && steps.meta.outputs.scan_image != '' }} id: cis_json - with: - entrypoint: trivy - args: "image ${{ env.input }} ${{ steps.meta.outputs.scan_image }} --compliance ${{ env.compliance }} -f json --ignore-unfixed -o ${{ steps.meta.outputs.cis_json_file }}" + shell: bash + run: | + trivy image ${{ env.input }} \ + ${{ steps.meta.outputs.scan_image }} \ + --compliance ${{ env.compliance }} \ + -f json \ + --ignore-unfixed \ + -o ${{ steps.meta.outputs.cis_json_file }} \ + ${{ inputs.trivy_db_cache != '' && '--cache-dir ~/.cache/trivy --skip-db-update' || '' }} env: compliance: docker-cis-1.6.0 input: ${{ steps.docker_tar.outputs.files_exists == 'true' && '--input' || '' }} @@ -324,10 +377,15 @@ runs: - name: Inspect docker-cis report if: ${{ inputs.skip_cis_scan != 'true' && steps.meta.outputs.scan_image != '' }} - uses: docker://aquasec/trivy:0.55.2 - with: - entrypoint: trivy - args: "image ${{ env.input }} ${{ steps.meta.outputs.scan_image }} --compliance ${{ env.compliance }} -f table --ignore-unfixed --exit-code ${{ env.exit-code }}" + shell: bash + run: | + trivy image ${{ env.input }} \ + ${{ steps.meta.outputs.scan_image }} \ + --compliance ${{ env.compliance }} \ + -f table \ + --ignore-unfixed \ + --exit-code ${{ env.exit-code }} \ + ${{ inputs.trivy_db_cache != '' && '--cache-dir ~/.cache/trivy --skip-db-update' || '' }} env: exit-code: ${{ (steps.meta.outputs.global_enforce_build_failure == 'true' || inputs.fail_build == 'true') && '1' || '0' }} compliance: docker-cis-1.6.0