name: Scheduled Security Scan # Visibility-only re-scan of the published image and a fresh build of main. # Surfaces CVEs disclosed between releases by uploading SARIF to GitHub Code # Scanning. The PR-blocking gate in ci.yml and the release-blocking gate in # docker-publish.yml are unchanged; this workflow only writes findings. on: schedule: - cron: '0 0 * * *' # Daily 00:00 UTC workflow_dispatch: # Prevent overlap when a manual workflow_dispatch fires while the daily cron # run is still in flight. cancel-in-progress is safe here: the workflow only # uploads SARIF for visibility and has no side effects on the registry. concurrency: group: security-scan cancel-in-progress: true permissions: contents: read jobs: scan-published: name: Trivy SARIF (published :latest) runs-on: ubuntu-latest timeout-minutes: 15 permissions: contents: read security-events: write steps: - name: Checkout (trivy.yaml + VEX) uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # Same SHA-pinned action used by the PR-blocking and release-blocking # scans. The trivy binary version is whatever this action SHA bundles; # Dependabot's all-actions group moves it forward when the action is # bumped, keeping a single source of truth. - name: Trivy scan of saelix/sencho:latest uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 with: image-ref: saelix/sencho:latest format: sarif output: trivy-published.sarif severity: 'CRITICAL,HIGH,MEDIUM' trivy-config: trivy.yaml ignore-unfixed: false # if: always() so findings still upload when trivy itself failed mid-run # (e.g. CVE DB pull timeout). The categorical separation from the # scan-main job below keeps the two result sets distinct in the UI. - name: Upload SARIF to code scanning if: always() uses: github/codeql-action/upload-sarif@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3 with: sarif_file: trivy-published.sarif category: trivy-published-image scan-main: name: Trivy SARIF (main HEAD build) runs-on: ubuntu-latest timeout-minutes: 25 permissions: contents: read security-events: write steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Set up Docker Buildx uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4 # Mirrors the daily-cache-bust logic from ci.yml / docker-publish.yml so # the apk upgrade layer rebuilds at least once per calendar day. - name: Compute daily apk cache bust value id: apk-bust run: echo "date=$(date -u +%Y-%m-%d)" >> "$GITHUB_OUTPUT" - name: Build image from main HEAD uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7 with: context: . push: false load: true tags: localhost/sencho:scheduled-scan cache-from: type=gha build-args: | APK_CACHE_BUST=${{ steps.apk-bust.outputs.date }} - name: Trivy scan of fresh main build uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 with: image-ref: localhost/sencho:scheduled-scan format: sarif output: trivy-main.sarif severity: 'CRITICAL,HIGH,MEDIUM' trivy-config: trivy.yaml ignore-unfixed: false - name: Upload SARIF to code scanning if: always() uses: github/codeql-action/upload-sarif@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3 with: sarif_file: trivy-main.sarif category: trivy-main-head