From 7f2f021c56aaaad2b5af7c79c5513f766e87e681 Mon Sep 17 00:00:00 2001 From: Valera V Harseko Date: Fri, 18 Sep 2026 19:30:17 +0300 Subject: [PATCH] Add Trivy vulnerability scanning for Docker images Scans the freshly built images (default and alpine) in build.yml for fixable CRITICAL/HIGH CVEs and uploads SARIF to code scanning, and adds a weekly docker-scan workflow that scans the published openidentityplatform/openicf:latest/:alpine images. Mirrors OpenIdentityPlatform/OpenDJ#854, with aquasecurity/trivy-action pinned by commit SHA to match the pinning convention introduced in #130. --- .github/workflows/build.yml | 52 +++++++++++++++++++++++++++ .github/workflows/docker-scan.yml | 59 +++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 .github/workflows/docker-scan.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 510c5188..7e982bae 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -118,6 +118,9 @@ jobs: !**/*-sources.jar build-docker: runs-on: 'ubuntu-latest' + permissions: + contents: read + security-events: write services: registry: image: registry:2 @@ -132,6 +135,7 @@ jobs: run: | export git_version_last="$(curl -i -o - --silent https://api.github.com/repos/OpenIdentityPlatform/OpenICF/releases/latest | grep -m1 "\"name\"" | cut -d\" -f4)" ; echo "last release: $git_version_last" echo "release_version=$git_version_last" >> $GITHUB_ENV + echo "image_repository=${GITHUB_REPOSITORY,,}" >> $GITHUB_ENV - name: Docker meta id: meta uses: docker/metadata-action@v6 @@ -164,8 +168,33 @@ jobs: docker run --rm -it -d --memory="1g" --name=test localhost:5000/${GITHUB_REPOSITORY,,}:${{ env.release_version }} timeout 3m bash -c 'until docker inspect --format="{{json .State.Health.Status}}" test | grep -q \"healthy\"; do sleep 10; done' docker logs test + - name: Scan image for vulnerabilities (Trivy) + # trivy resolves the image from the local Docker daemon, so only the runner's + # linux/amd64 manifest is scanned; cache: false keeps the ~1GB trivy DBs from + # evicting the m2-repository caches out of the repo's 10GB actions-cache quota + uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 + with: + image-ref: localhost:5000/${{ env.image_repository }}:${{ env.release_version }} + format: sarif + output: trivy-results.sarif + severity: CRITICAL,HIGH + limit-severities-for-sarif: true + ignore-unfixed: true + scanners: vuln + cache: false + - name: Upload Trivy report to GitHub Security + uses: github/codeql-action/upload-sarif@v4 + # upload even if a preceding step failed, but not without a report to upload + if: ${{ always() && hashFiles('trivy-results.sarif') != '' }} + with: + sarif_file: trivy-results.sarif + # distinct from the docker-scan.yml categories, which track the published images + category: trivy-build-default build-docker-alpine: runs-on: 'ubuntu-latest' + permissions: + contents: read + security-events: write services: registry: image: registry:2 @@ -180,6 +209,7 @@ jobs: run: | export git_version_last="$(curl -i -o - --silent https://api.github.com/repos/OpenIdentityPlatform/OpenICF/releases/latest | grep -m1 "\"name\"" | cut -d\" -f4)" ; echo "last release: $git_version_last" echo "release_version=$git_version_last" >> $GITHUB_ENV + echo "image_repository=${GITHUB_REPOSITORY,,}" >> $GITHUB_ENV - name: Docker meta id: meta uses: docker/metadata-action@v6 @@ -213,3 +243,25 @@ jobs: docker run --rm -it -d --memory="1g" --name=test localhost:5000/${GITHUB_REPOSITORY,,}:${{ env.release_version }}-alpine timeout 3m bash -c 'until docker inspect --format="{{json .State.Health.Status}}" test | grep -q \"healthy\"; do sleep 10; done' docker logs test + - name: Scan image for vulnerabilities (Trivy) + # trivy resolves the image from the local Docker daemon, so only the runner's + # linux/amd64 manifest is scanned; cache: false keeps the ~1GB trivy DBs from + # evicting the m2-repository caches out of the repo's 10GB actions-cache quota + uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 + with: + image-ref: localhost:5000/${{ env.image_repository }}:${{ env.release_version }}-alpine + format: sarif + output: trivy-results.sarif + severity: CRITICAL,HIGH + limit-severities-for-sarif: true + ignore-unfixed: true + scanners: vuln + cache: false + - name: Upload Trivy report to GitHub Security + uses: github/codeql-action/upload-sarif@v4 + # upload even if a preceding step failed, but not without a report to upload + if: ${{ always() && hashFiles('trivy-results.sarif') != '' }} + with: + sarif_file: trivy-results.sarif + # distinct from the docker-scan.yml categories, which track the published images + category: trivy-build-alpine diff --git a/.github/workflows/docker-scan.yml b/.github/workflows/docker-scan.yml new file mode 100644 index 00000000..60f70259 --- /dev/null +++ b/.github/workflows/docker-scan.yml @@ -0,0 +1,59 @@ +# The contents of this file are subject to the terms of the Common Development and +# Distribution License (the License). You may not use this file except in compliance with the +# License. +# +# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the +# specific language governing permission and limitations under the License. +# +# When distributing Covered Software, include this CDDL Header Notice in each file and include +# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL +# Header, with the fields enclosed by brackets [] replaced by your own identifying +# information: "Portions copyright [year] [name of copyright owner]". +# +# Copyright 2026 3A Systems, LLC. + +# Scans the published Docker images for known vulnerabilities: new CVEs surface in +# already-released images (mostly via the base image), without any change in this repository. +name: Docker Scan + +on: + schedule: + - cron: '30 5 * * 1' + workflow_dispatch: + +permissions: + contents: read + +jobs: + scan: + # Do not run the scheduled scan in forks; manual runs are always allowed. + if: github.event_name == 'workflow_dispatch' || github.repository == 'OpenIdentityPlatform/OpenICF' + runs-on: ubuntu-latest + permissions: + contents: read + security-events: write + strategy: + fail-fast: false + matrix: + tag: [ 'latest', 'alpine' ] + steps: + - uses: actions/checkout@v7 + - name: Scan openidentityplatform/openicf:${{ matrix.tag }} (Trivy) + # unlike the build.yml gate, unfixed CVEs are reported too: surfacing them in + # already-released images is the point of this workflow + uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 + with: + image-ref: openidentityplatform/openicf:${{ matrix.tag }} + format: sarif + output: trivy-${{ matrix.tag }}.sarif + severity: CRITICAL,HIGH + limit-severities-for-sarif: true + scanners: vuln + cache: false + - name: Upload report to GitHub Security + uses: github/codeql-action/upload-sarif@v4 + # upload even if a preceding step failed, but not without a report to upload + if: ${{ always() && hashFiles(format('trivy-{0}.sarif', matrix.tag)) != '' }} + with: + sarif_file: trivy-${{ matrix.tag }}.sarif + category: trivy-image-${{ matrix.tag }}