From 56714fdad0924a2a2f54f210e26f250c7692bdf2 Mon Sep 17 00:00:00 2001 From: Albert Mavashev Date: Sun, 3 May 2026 07:04:14 -0400 Subject: [PATCH] ops(security): scan main on push too, so post-fix scans clear stale alerts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trivy alerts on the main-branch alert track only auto-close when a SARIF scan publishes against refs/heads/main with the same (workflow, job, category) tuple. Currently pr-container-scan.yml only triggers on pull_request, so scans always upload against PR refs — main-track alerts go stale after every fix merge. Concrete impact: cycles-server-events had 13 stale gnutls alerts after PR #54 (the gnutls fix) merged. Required a no-op Dockerfile-comment PR (#57) to retrigger the scan and finally clear them. Fix: add 'push: branches: [main]' trigger with the same paths filter. Now every fix-merge to main re-scans and updates the alert track. Side effect: image tag template changed from 'pr-N' to 'scan-{N or sha}' so it's defined for both event types. Image is local-only (load:true, push:false) so the tag value doesn't matter to anything downstream. --- .github/workflows/pr-container-scan.yml | 31 +++++++++++++++++-------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/.github/workflows/pr-container-scan.yml b/.github/workflows/pr-container-scan.yml index d8c0019..07b1d77 100644 --- a/.github/workflows/pr-container-scan.yml +++ b/.github/workflows/pr-container-scan.yml @@ -1,12 +1,15 @@ -name: PR Container Scan +name: Container Scan # Runs Trivy against a locally-built image on PRs that change the Dockerfile -# or Maven dependencies. Paths filter is deliberate: most PRs don't touch the -# image, and running this on every PR would add ~5-10 min of build time for -# no benefit. When the filter fires, we catch base-image / added-dependency -# CVEs before merge rather than discovering them at release-cut time. +# or Maven dependencies, AND on every push to main with the same paths filter. +# Paths filter is deliberate: most PRs don't touch the image, and running this +# on every PR would add ~5-10 min of build time for no benefit. # -# Never pushes — this is PR-time feedback only. release.yml continues to run +# The push:main trigger ensures stale Trivy alerts auto-close after a fix +# lands — without it, the SARIF only ever uploads against PR refs and the +# main-branch alert track goes stale after every fix merge. +# +# Never pushes images — this is feedback only. release.yml continues to run # the authoritative scan at release publish time (with the real version tag). on: @@ -17,6 +20,14 @@ on: - 'pom.xml' - '**/pom.xml' - '.github/workflows/pr-container-scan.yml' + push: + branches: [main] + paths: + - 'Dockerfile' + - '**/Dockerfile' + - 'pom.xml' + - '**/pom.xml' + - '.github/workflows/pr-container-scan.yml' permissions: read-all @@ -41,16 +52,16 @@ jobs: context: . push: false load: true - tags: ghcr.io/runcycles/cycles-server:pr-${{ github.event.pull_request.number }} + tags: ghcr.io/runcycles/cycles-server:scan-${{ github.event.pull_request.number || github.sha }} build-args: | - APP_VERSION=pr-${{ github.event.pull_request.number }} + APP_VERSION=scan-${{ github.event.pull_request.number || github.sha }} cache-from: type=gha cache-to: type=gha,mode=max - name: Trivy vulnerability scan uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 with: - image-ref: ghcr.io/runcycles/cycles-server:pr-${{ github.event.pull_request.number }} + image-ref: ghcr.io/runcycles/cycles-server:scan-${{ github.event.pull_request.number || github.sha }} severity: 'HIGH,CRITICAL' ignore-unfixed: true format: 'sarif' @@ -62,4 +73,4 @@ jobs: uses: github/codeql-action/upload-sarif@e46ed2cbd01164d986452f91f178727624ae40d7 # v4 with: sarif_file: 'trivy-results.sarif' - category: trivy-container-pr + category: trivy-container-pr # category kept stable so push-to-main scans clear PR-track alerts