Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions .github/workflows/trivy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
name: Trivy Security Scan

on:
pull_request:
push:
branches:
- main
schedule:
# Weekly full scan, Mondays 06:00 UTC.
- cron: "0 6 * * 1"
workflow_dispatch:

permissions:
contents: read

# Cancel superseded PR runs; non-PR runs get a unique group so they are never
# interrupted (mirrors ci.yml).
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
cancel-in-progress: true

jobs:
# Blocking gate on PRs and pushes to main: fail only on fixable CRITICAL/HIGH
# vulnerabilities in Go dependencies, so a red check always has an actionable
# fix (bump the dependency). Vulns with no upstream fix don't wedge every PR.
scan-pr:
name: Dependency Scan
if: github.event_name == 'pull_request' || github.event_name == 'push'
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
security-events: write # upload SARIF to code scanning
steps:
- name: Checkout code
uses: actions/checkout@v7

# SARIF report for the Security tab covers all severities and never fails
# the job (the gate below owns pass/fail). trivy-action ignores severity
# filters when format is sarif, so this cannot double as the gate.
- name: Run Trivy (SARIF report)
uses: aquasecurity/trivy-action@v0.36.0
with:
scan-type: fs
scanners: vuln
format: sarif
output: trivy-results.sarif

# Fork-PR tokens have no security-events:write, so skip the upload there
# (the scan + gate still run).
- name: Upload SARIF to code scanning
if: always() && github.event.pull_request.head.repo.fork != true
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: trivy-results.sarif

# The blocking gate: fail only on fixable CRITICAL/HIGH vulnerabilities.
- name: Run Trivy (fixable CRITICAL/HIGH gate)
uses: aquasecurity/trivy-action@v0.36.0
with:
scan-type: fs
scanners: vuln
severity: CRITICAL,HIGH
ignore-unfixed: true
exit-code: "1"
format: table

# Weekly full scan: every severity, including vulns with no fix yet. New CVEs
# land against unchanged code, so this catches what the PR gate never sees.
# Results go to the Security tab (code scanning) — watchers subscribed to
# security alerts get notified there, no Slack/webhook plumbing.
scan-weekly:
name: Full Scan
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
security-events: write # upload SARIF to code scanning
steps:
- name: Checkout code
uses: actions/checkout@v7

- name: Run Trivy (all severities)
uses: aquasecurity/trivy-action@v0.36.0
with:
scan-type: fs
scanners: vuln
format: sarif
output: trivy-results.sarif

- name: Upload SARIF to code scanning
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: trivy-results.sarif
Loading