Skip to content

fix(ci): make the periodic security scan actually report findings - #834

Merged
danbarr merged 3 commits into
mainfrom
fix/periodic-scan-reporting
Aug 5, 2026
Merged

fix(ci): make the periodic security scan actually report findings#834
danbarr merged 3 commits into
mainfrom
fix/periodic-scan-reporting

Conversation

@danbarr

@danbarr danbarr commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Closes #829

The weekly scan has failed every run for at least five weeks and has never filed an issue. Two independent problems, both fixed here.

1. The job aborted before it could report. The SARIF scan step ran at severity-cutoff: low with no fail-build, and anchore/scan-action defaults that to true, so it failed on essentially any finding. Upload SARIF survived on if: always(), but the JSON scan, the count check, and the issue creation were all skipped. Both scan steps now set fail-build: false so Check for critical or high issues decides the outcome.

2. Its alerting threshold sat above the publish gate. build-containers blocks at high, while this filed issues only on critical, so a finding serious enough to block a publish produced no notification. high was already computed and then unused. The gate is now critical + high > 0, and the JSON step matches the publish gate exactly (severity-cutoff: high, only-fixed: true).

The SARIF feed stays deliberately broad. Aligning it too would have narrowed the Security tab, since only-fixed drops findings with no available fix and the periodic-grype-* categories carry them today. It keeps only fail-build: false. Worth knowing: severity-cutoff only feeds grype's --fail-on and does not filter the report, so only-fixed is the setting that would have cost coverage.

Also here: issues are labelled by what was actually found rather than always critical, and the issue body gained a high-severity detail block, since "5 high" with no specifics is not actionable.

Verification

This cannot be exercised without a scheduled run, so the checks are static:

  • YAML parses.
  • Input names and defaults read from the pinned action rather than from memory: fail-build does default to "true", confirming the mechanism; severity-cutoff is only passed as --fail-on and does not filter output, so the jq counts stay correct.
  • actionlint is not installed here, so it was not run.
  • jq handles absent and empty .matches, giving should_create_issue=false rather than an arithmetic error.
  • Step paths after the change: on findings, every step now runs through to issue creation. Only a genuine error (registry auth, missing image, grype crash) fails a scan step, and Upload SARIF and Upload scan results keep if: always().

🤖 Generated with Claude Code

danbarr and others added 3 commits August 5, 2026 15:12
The weekly periodic-security-scan has never filed an issue. Two
independent problems, both fixed here.

First, the scan steps relied on anchore/scan-action's default
fail-build: true with a "low" severity cutoff and no only-fixed, so the
SARIF scan failed on essentially any finding and aborted the job. Only
"Upload SARIF to GitHub Security" survived via if: always(); the JSON
scan, the count check, and the issue-filing step were all skipped. Both
scan steps now set fail-build: false so the check step decides the
outcome instead of the scanner aborting the job.

Second, the thresholds did not match the publish gate. build-containers
blocks publishing at severity-cutoff: high with only-fixed: true, while
this workflow scanned at low without only-fixed and then filed an issue
only when critical > 0. A high finding was therefore enough to block a
release but produced no notification, and the already-computed "high"
output went unused. Both scan steps now use severity-cutoff: high with
only-fixed: true, and should_create_issue is true when critical + high
is greater than zero.

Also lists the top high-severity findings in the issue body alongside
the criticals, and updates step names and summary wording to match the
new thresholds. Issue dedup and labels are unchanged.

Refs #829

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Aligning both scan steps with the publish gate would have narrowed the
Security tab: only-fixed drops findings that have no fix available, and
the periodic-grype-* categories currently carry them.

Keep only-fixed on the JSON step, which drives the issue-filing decision
and should match what blocks a publish, and leave the SARIF feed broad so
existing code scanning coverage is unchanged.
Now that a high finding can file an issue, a fixed label array would mark
high-only issues as critical. Build the list from the counts instead, so
critical and high are applied only when present. security and grype stay
unconditional since the dedup query matches on them.
@danbarr
danbarr merged commit 16ff645 into main Aug 5, 2026
2 checks passed
@danbarr
danbarr deleted the fix/periodic-scan-reporting branch August 5, 2026 20:16
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.

fix(ci): periodic-security-scan never reports findings, and its thresholds do not match the publish gate

2 participants