Skip to content

ci(trivy-fs): surface the concrete findings that fail the gate#375

Closed
seonghobae wants to merge 1 commit into
mainfrom
fix/trivy-fs-print-findings
Closed

ci(trivy-fs): surface the concrete findings that fail the gate#375
seonghobae wants to merge 1 commit into
mainfrom
fix/trivy-fs-print-findings

Conversation

@seonghobae

Copy link
Copy Markdown
Contributor

Problem

The central trivy-fs job (.github/workflows/security-scan.yml) is a HARD gate that fails PRs across the org, but it writes findings only to trivy-results.sarif. On failure the job log shows nothing but:

##[error]Process completed with exit code 1.

Every blocked PR (e.g. scopeweave #285/#283/#282/#281/#279/#271/#204) had to download and parse the uploaded SARIF by hand to learn what failed. That is exactly the "check fails opaquely" anti-pattern.

Investigation (scopeweave, live)

Read the actual SARIF for the failing runs via the code-scanning analyses API (results_count, not a stale-DB local scan). All blocked scopeweave PRs share 4 findings inherited from the default branch:

Rule Location Trivy severity Summary
DS-0026 Dockerfile:1 LOW Add HEALTHCHECK instruction
KSV-0020 infra/k8s/deployment.yaml:25 LOW set securityContext.runAsUser > 10000
KSV-0021 infra/k8s/deployment.yaml:25 LOW set securityContext.runAsGroup > 10000
KSV-0110 infra/k8s/deployment.yaml:3 LOW set a non-default metadata.namespace

These are LOW misconfigs that leak past the job's severity: CRITICAL,HIGH filter under Trivy v0.70.0 in SARIF output mode (fixed upstream by 0.71.x). Remediation of the findings themselves lands at the scopeweave shared base in ContextualWisdomLab/scopeweave#289 (verified locally: trivy fs --scanners misconfig exits 0 on that branch).

Change

Add a read-only if: failure() step that parses the generated SARIF and prints each finding — rule id, Trivy severity, file:line, message — directly in the job log:

Trivy filesystem scan reported 4 finding(s):
  [LOW (security-severity=2.0)] DS-0026 Dockerfile:1 — Add HEALTHCHECK instruction in your Dockerfile
  [LOW (security-severity=2.0)] KSV-0020 infra/k8s/deployment.yaml:25 — ... runAsUser > 10000
  ...
Remediate each finding at the shared base (default branch) so open PRs inherit the fix.

The scan step still owns the pass/fail decision. The gate is unchanged — no severity change, no exit-code change, no .trivyignore. This only makes the existing failure legible.

🤖 Generated with Claude Code

The trivy-fs job writes findings only to trivy-results.sarif, so a failing
scan logs nothing but "Process completed with exit code 1" — every blocked
PR had to inspect the uploaded SARIF to learn what actually failed.

Add a read-only `if: failure()` step that parses the generated SARIF and
prints each finding (rule id, Trivy severity, file:line, message) directly
in the job log. The scan step still owns the pass/fail decision; the gate is
unchanged (no severity/exit-code weakening).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RTAMs4bpSZS77Xe3RQjv9P
@seonghobae

Copy link
Copy Markdown
Contributor Author

Superseded by #382, which includes this Trivy SARIF-to-log visibility fix plus central workflow token and CI regression fixes.

@seonghobae seonghobae closed this Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant