name: Container CVE Scan (development) on: push: branches: ["development"] workflow_dispatch: jobs: cve-scan: name: Scan backend/frontend images for CVEs runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build backend image (local) uses: docker/build-push-action@v6 with: context: ./backend file: ./backend/Dockerfile push: false load: true tags: nexapg-backend:dev-scan provenance: false sbom: false - name: Build frontend image (local) uses: docker/build-push-action@v6 with: context: ./frontend file: ./frontend/Dockerfile push: false load: true tags: nexapg-frontend:dev-scan build-args: | VITE_API_URL=/api/v1 provenance: false sbom: false - name: Trivy scan (backend) uses: aquasecurity/trivy-action@0.24.0 with: image-ref: nexapg-backend:dev-scan format: json output: trivy-backend.json severity: UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL ignore-unfixed: false exit-code: 0 - name: Trivy scan (frontend) uses: aquasecurity/trivy-action@0.24.0 with: image-ref: nexapg-frontend:dev-scan format: json output: trivy-frontend.json severity: UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL ignore-unfixed: false exit-code: 0 - name: Summarize Trivy severities run: | python - <<'PY' import json from collections import Counter def summarize(path): c = Counter() with open(path, "r", encoding="utf-8") as f: data = json.load(f) for result in data.get("Results", []): for v in result.get("Vulnerabilities", []) or []: c[v.get("Severity", "UNKNOWN")] += 1 for sev in ["CRITICAL", "HIGH", "MEDIUM", "LOW", "UNKNOWN"]: c.setdefault(sev, 0) return c for label, path in [("backend", "trivy-backend.json"), ("frontend", "trivy-frontend.json")]: s = summarize(path) print(f"===== Trivy {label} =====") print(f"CRITICAL={s['CRITICAL']} HIGH={s['HIGH']} MEDIUM={s['MEDIUM']} LOW={s['LOW']} UNKNOWN={s['UNKNOWN']}") print() PY - name: Docker Scout scan (backend) continue-on-error: true run: | docker run --rm -v /var/run/docker.sock:/var/run/docker.sock docker/scout-cli:latest \ cves nexapg-backend:dev-scan --only-severity critical,high,medium,low > scout-backend.txt - name: Docker Scout scan (frontend) continue-on-error: true run: | docker run --rm -v /var/run/docker.sock:/var/run/docker.sock docker/scout-cli:latest \ cves nexapg-frontend:dev-scan --only-severity critical,high,medium,low > scout-frontend.txt - name: Print scan summary run: | echo "===== Docker Scout backend =====" test -f scout-backend.txt && cat scout-backend.txt || echo "scout-backend.txt not available" echo echo "===== Docker Scout frontend =====" test -f scout-frontend.txt && cat scout-frontend.txt || echo "scout-frontend.txt not available" - name: Upload scan reports uses: actions/upload-artifact@v3 with: name: container-cve-scan-reports path: | trivy-backend.json trivy-frontend.json scout-backend.txt scout-frontend.txt