name: Trivy Vulnerability Scanner permissions: {} on: pull_request: branches: - develop push: branches: - develop merge_group: types: [checks_requested] jobs: scan: name: Scan for Vulnerabilities runs-on: ubuntu-latest permissions: issues: write contents: read security-events: write steps: - name: Checkout code uses: actions/checkout@v6.0.2 - name: Install Trivy run: | curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin - name: Run Trivy scan id: trivy-scan continue-on-error: true run: | # Generate SARIF report first trivy fs \ --format template \ --template '@/contrib/sarif.tpl' \ --output trivy-results.sarif \ --severity CRITICAL,HIGH \ --vuln-type os,library \ --no-progress . # Generate JSON report and fail step if vulnerabilities are found trivy fs \ --format json \ --output trivy-results.json \ --severity CRITICAL,HIGH \ --vuln-type os,library \ --no-progress \ --exit-code 1 . - name: Upload Trivy JSON report as artifact if: steps.trivy-scan.outcome == 'failure' uses: actions/upload-artifact@v7 with: name: trivy-json-report path: trivy-results.json retention-days: 1 - name: Upload SARIF to GitHub Security tab if: always() uses: github/codeql-action/upload-sarif@v4 with: sarif_file: 'trivy-results.sarif' category: trivy-fs - name: Print vulnerability details and fail job if: steps.trivy-scan.outcome == 'failure' run: | echo "🛑 Trivy scan found CRITICAL or HIGH severity vulnerabilities. Details:" echo "--------------------------------------------------------------------" # Parse the JSON report and print a summary of each vulnerability jq -r '.Results[] | .Target as $target | if .Vulnerabilities then .Vulnerabilities[] | "File: \($target)\nPackage: \(.PkgName) (\(.InstalledVersion))\nID: \(.VulnerabilityID)\nSeverity: \(.Severity)\nLink: \(.PrimaryURL)\n--------------------------------------------------------------------" else empty end' trivy-results.json # Exit with a failure code to fail the workflow exit 1