Skip to content
Closed
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
80 changes: 80 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,86 @@ jobs:
- run: bandit -r . -x ./tests --severity-level medium -f json -o bandit-report.json || true
- run: bandit -r . -x ./tests --severity-level high

backend-vuln-scan:
name: Backend Dependency Vulnerability Scan (advisory)
runs-on: ubuntu-latest
defaults:
run:
working-directory: backend
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
# Match backend/Dockerfile (python:3.13-slim) so the audited
# dependency resolution mirrors what actually ships.
python-version: "3.13"
cache: pip
- run: pip install -r requirements.txt pip-audit
Comment thread
greptile-apps[bot] marked this conversation as resolved.
# Advisory only: known advisories (e.g. transitive starlette/mcp/
# python-multipart CVEs) already exist in the dependency tree today,
# and shouldn't block CI. Flip this to blocking (drop
# continue-on-error) once those are triaged and cleared.
- name: pip-audit
run: pip-audit
continue-on-error: true

frontend-vuln-scan:
name: Frontend Dependency Vulnerability Scan (advisory)
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontend
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: npm
cache-dependency-path: frontend/package-lock.json
- run: npm ci
# Advisory only: known advisories (next/glob/prismjs/postcss/js-yaml)
# already exist in the dependency tree today, and shouldn't block CI.
# Flip this to blocking (drop continue-on-error) once those are
# triaged and cleared.
- name: npm audit
run: npm audit
continue-on-error: true

image-scan:
name: Container Image Vulnerability Scan (advisory)
runs-on: ubuntu-latest
strategy:
matrix:
include:
- image: trainable-backend
context: ./backend
- image: trainable-frontend
context: ./frontend
target: runner
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- name: Build ${{ matrix.image }} image (local only, not pushed)
uses: docker/build-push-action@v5
with:
context: ${{ matrix.context }}
target: ${{ matrix.target || '' }}
push: false
load: true
tags: ${{ matrix.image }}:ci-scan
# Advisory only: base-image and OS-package advisories aren't triaged
# yet and shouldn't block CI. Flip to blocking (drop
# continue-on-error, or set exit-code back to 1 without the wrapper)
# once they are.
- name: Trivy scan
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
continue-on-error: true
with:
image-ref: ${{ matrix.image }}:ci-scan
format: table
severity: "CRITICAL,HIGH"
exit-code: "1"
Comment on lines +158 to +165

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Trivy findings stay in job logs only — the scan outputs format: table to stdout. GitHub's Security tab (Dependabot/Code Scanning) can ingest SARIF uploads, which would surface CRITICAL/HIGH findings directly on the PR without reviewers having to dig into job logs. Adding format: sarif, output: trivy-results.sarif, and an actions/upload-artifact (or github/codeql-action/upload-sarif) step after the scan would make the advisory findings much more visible over time.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Claude Code


frontend-lint:
name: Frontend Lint & Typecheck
runs-on: ubuntu-latest
Expand Down