Security #1006
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Security | |
| on: | |
| pull_request: | |
| branches: | |
| - main | |
| paths: | |
| - 'bun.lock' | |
| - 'package.json' | |
| - 'services/*/package.json' | |
| # Dockerfile + dockerignore changes alter what trivy's misconfig | |
| # scanner sees on the fs-scan path; .trivyignore.yaml changes can | |
| # silently un-suppress findings. Round-2 R2-B11 found this branch | |
| # added new Dockerfiles + a trivyignore without re-triggering the | |
| # security scan — PRs went out blind. | |
| - 'services/*/Dockerfile' | |
| - 'services/*/Dockerfile.dockerignore' | |
| - '.trivyignore.yaml' | |
| - '.github/workflows/security.yml' | |
| push: | |
| branches: | |
| - main | |
| paths: | |
| - 'bun.lock' | |
| - 'package.json' | |
| - 'services/*/package.json' | |
| - 'services/*/Dockerfile' | |
| - 'services/*/Dockerfile.dockerignore' | |
| - '.trivyignore.yaml' | |
| - '.github/workflows/security.yml' | |
| schedule: | |
| - cron: '0 3 * * 1' # Monday 03:00 UTC | |
| workflow_dispatch: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| # --------------------------------------------------------------------------- | |
| # Audit JS dependencies for known advisories. | |
| # Reports the full advisory list (all severities) in the job summary, then a | |
| # gate fails the build on HIGH or CRITICAL production advisories. If an | |
| # advisory has no fixed release, suppress it explicitly: a dated accept-risk | |
| # entry in .trivyignore.yaml for the Trivy gate, and --ignore=<advisory-id> | |
| # on the gate command below for bun audit. | |
| # --------------------------------------------------------------------------- | |
| bun-audit: | |
| name: Bun audit | |
| if: github.event.pull_request.draft != true | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 | |
| with: | |
| bun-version: '1.3.12' | |
| - name: Run bun audit (report) | |
| # Full advisory list for visibility; does not fail the build itself. | |
| continue-on-error: true | |
| run: bun audit --prod | tee bun-audit.txt | |
| - name: Summary | |
| if: always() | |
| run: | | |
| echo "## Bun audit" >> "$GITHUB_STEP_SUMMARY" | |
| echo '```' >> "$GITHUB_STEP_SUMMARY" | |
| tail -n 50 bun-audit.txt >> "$GITHUB_STEP_SUMMARY" || true | |
| echo '```' >> "$GITHUB_STEP_SUMMARY" | |
| - name: Gate on high/critical advisories | |
| # The blocking gate: fail on HIGH or CRITICAL production advisories. | |
| # pipefail so tee does not mask a non-zero exit. | |
| run: | | |
| set -o pipefail | |
| bun audit --prod --audit-level=high | tee bun-audit-gate.txt | |
| # --------------------------------------------------------------------------- | |
| # Scan source tree for known CVEs in dependencies + misconfigurations + secrets. | |
| # Uploads SARIF to GitHub Security (all scanners, HIGH+CRITICAL, informational), | |
| # then a vuln-only gate fails the build on FIXABLE HIGH or CRITICAL dependency | |
| # CVEs. Secret/misconfig findings stay informational (SARIF) to avoid blocking | |
| # on scanner noise. Unlike bun audit, this scans the whole tree (bun.lock, | |
| # every workspace) with no prod/dev split; unfixable findings are suppressed | |
| # via dated accept-risk entries in .trivyignore.yaml. | |
| # --------------------------------------------------------------------------- | |
| trivy-fs: | |
| name: Trivy filesystem scan | |
| if: github.event.pull_request.draft != true | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| permissions: | |
| contents: read | |
| security-events: write | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - name: Run Trivy filesystem scan | |
| uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 | |
| with: | |
| scan-type: 'fs' | |
| scan-ref: '.' | |
| format: 'sarif' | |
| output: 'trivy-fs.sarif' | |
| severity: 'HIGH,CRITICAL' | |
| exit-code: '0' | |
| scanners: 'vuln,secret,misconfig' | |
| ignore-unfixed: true | |
| # Per-path misconfig suppressions live in .trivyignore.yaml; the | |
| # plain .trivyignore is auto-detected but cannot scope by path. | |
| trivyignores: '.trivyignore.yaml' | |
| # Skip handlebars Dockerfile templates: handlebars syntax confuses | |
| # the misconfig scanner. The generated Dockerfiles are scanned | |
| # downstream when each service runs its own build. | |
| skip-files: 'tools/plop/templates/**/Dockerfile.hbs' | |
| - name: Upload SARIF | |
| uses: github/codeql-action/upload-sarif@e46ed2cbd01164d986452f91f178727624ae40d7 # v4 | |
| if: always() | |
| with: | |
| sarif_file: 'trivy-fs.sarif' | |
| category: 'trivy-fs' | |
| # Blocking gate: fail the build on FIXABLE high or critical dependency | |
| # vulnerabilities. Runs vuln-only (secret/misconfig stay informational via | |
| # the SARIF upload above) and honours the same path-scoped ignore file, so | |
| # a real, patchable high/critical CVE cannot merge silently. | |
| - name: Trivy vulnerability gate (HIGH/CRITICAL) | |
| uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 | |
| with: | |
| scan-type: 'fs' | |
| scan-ref: '.' | |
| format: 'table' | |
| severity: 'HIGH,CRITICAL' | |
| exit-code: '1' | |
| scanners: 'vuln' | |
| ignore-unfixed: true | |
| trivyignores: '.trivyignore.yaml' | |
| skip-files: 'tools/plop/templates/**/Dockerfile.hbs' | |
| - name: Summary | |
| if: always() | |
| run: | | |
| echo "## Trivy filesystem scan complete" >> "$GITHUB_STEP_SUMMARY" | |
| echo "Results uploaded to the Security tab under category \`trivy-fs\`." >> "$GITHUB_STEP_SUMMARY" |