feat(ci): extend daily scan to full BOM image set at Medium+ with auto-generated VEX drafts (#1473)#1516
feat(ci): extend daily scan to full BOM image set at Medium+ with auto-generated VEX drafts (#1473)#1516mohityadav8 wants to merge 7 commits into
Conversation
📝 WalkthroughWalkthroughA new Python script Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/scripts/gen-vex-drafts.py:
- Around line 223-226: The empty scan-pairs branch in gen-vex-drafts.py
currently exits successfully, which masks a broken scan-bom artifact/output
contract. Update the scan_pairs check in the main flow so that when no pairs are
found it records the zero count if needed but fails the job with a non-zero exit
instead of returning 0, keeping the failure tied to the vex-draft execution
path.
In @.github/workflows/vuln-scan-images.yaml:
- Around line 483-494: The bom-scan artifact filenames are keyed only by
SHORT_NAME, so different IMAGE references with the same basename can overwrite
each other in bom-scan-results and lose findings. Update the naming logic in the
bom-scan steps that write OUT, JSON_OUT, and the .ref file so each artifact uses
a collision-resistant identifier derived from the full image reference (for
example, include a sanitized registry/namespace or a hash) while keeping the
existing bom-scan-results flow intact. Make the same change wherever the same
basename-based naming is used in the related bom-scan sections to ensure every
image produces unique .txt, .json, and .ref outputs.
- Around line 695-699: The Slack/log text in the BOM medium summary is
overstating the result by saying a VEX draft PR was opened whenever
BOM_TOTAL_MEDIUM is greater than zero. Update the logic around BOM_MEDIUM_LINE
so it only mentions an opened VEX draft PR when the same condition used by
vex-draft indicates a new PR was actually created (for example, new_count > 0),
and otherwise keep the message limited to the upstream medium total. Use the
BOM_TOTAL_MEDIUM/BOM_MEDIUM_LINE block and the vex-draft PR-opening condition as
the key symbols to align the message with actual behavior.
- Around line 460-531: The BOM scan workflow currently skips artifact creation
when anchore/scan-action fails before JSON output exists, so failed images are
lost from downstream Slack/VEX processing. Update the extraction step that reads
steps.scan.outputs.json to run under always(), and make the Upload BOM scan
result step run always() as well so bom-scan-results is still published even on
failures. In the extraction logic, keep the existing “scan output missing” path
but safely handle an empty JSON_FILE/output situation without failing the job.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Enterprise
Run ID: 261f144d-9b3e-4e17-8b87-abea7b1c84c5
📒 Files selected for processing (2)
.github/scripts/gen-vex-drafts.py.github/workflows/vuln-scan-images.yaml
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Signed-off-by: Mohit Yadav <ymohit799057@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Signed-off-by: Mohit Yadav <ymohit799057@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Signed-off-by: Mohit Yadav <ymohit799057@gmail.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/vuln-scan-images.yaml (1)
511-517: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winAdd the missing
+before the related CVE suffix. The jq expression is syntactically invalid as written, so this step exits before generating the.txtsummary for high/critical matches.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/vuln-scan-images.yaml around lines 511 - 517, The jq expression used in the high/critical image scan summary is missing the concatenation operator before the related CVE suffix, which makes the `HIGH_IDS` assignment invalid. Update the jq filter in the `vuln-scan-images` workflow to concatenate `.artifact.name`, `.vulnerability.id`, and the optional related vulnerabilities string correctly, so the `HIGH_IDS` step can complete and produce the `.txt` summary.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In @.github/workflows/vuln-scan-images.yaml:
- Around line 511-517: The jq expression used in the high/critical image scan
summary is missing the concatenation operator before the related CVE suffix,
which makes the `HIGH_IDS` assignment invalid. Update the jq filter in the
`vuln-scan-images` workflow to concatenate `.artifact.name`,
`.vulnerability.id`, and the optional related vulnerabilities string correctly,
so the `HIGH_IDS` step can complete and produce the `.txt` summary.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Enterprise
Run ID: 961d25a7-79ff-47cc-802e-9dd8a3cc41dd
📒 Files selected for processing (2)
.github/scripts/gen-vex-drafts.py.github/workflows/vuln-scan-images.yaml
Signed-off-by: Mohit Yadav <ymohit799057@gmail.com>
Signed-off-by: Mohit Yadav <ymohit799057@gmail.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/vuln-scan-images.yaml (1)
699-709: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winSend the BOM Medium digest when Medium is the highest severity.
Line 706 skips Slack whenever Critical/High totals are zero, so
BOM_MEDIUM_LINEis never posted for Medium-only BOM findings despite the Medium+ reporting objective.Proposed fix
- # Only notify when critical or high vulnerabilities are found - if [[ "${TOTAL_CRITICAL}" -eq 0 && "${TOTAL_HIGH}" -eq 0 ]]; then + # Notify for Critical/High findings, or for the BOM Medium digest. + if [[ "${TOTAL_CRITICAL}" -eq 0 && "${TOTAL_HIGH}" -eq 0 && "${BOM_TOTAL_MEDIUM}" -eq 0 ]]; then echo "No critical or high vulnerabilities found, skipping Slack notification" echo -e "Vulnerability Scan: ${TIMESTAMP} (${SHORT_SHA})${NVIDIA_RESULTS}${BOM_MEDIUM_LINE}" exit 0 fi🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/vuln-scan-images.yaml around lines 699 - 709, The Slack notification gate in the vuln scan workflow is too narrow: the current check in the notification block only sends when Critical or High findings exist, so `BOM_MEDIUM_LINE` from the BOM digest is skipped for Medium-only cases. Update the logic around the existing `TOTAL_CRITICAL`, `TOTAL_HIGH`, and `BOM_MEDIUM_LINE` handling so Slack is still notified when Medium is the highest severity for BOM findings, while preserving the existing skip behavior for truly clean results. Use the notification section in `vuln-scan-images.yaml` and the surrounding severity totals to locate the fix.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In @.github/workflows/vuln-scan-images.yaml:
- Around line 699-709: The Slack notification gate in the vuln scan workflow is
too narrow: the current check in the notification block only sends when Critical
or High findings exist, so `BOM_MEDIUM_LINE` from the BOM digest is skipped for
Medium-only cases. Update the logic around the existing `TOTAL_CRITICAL`,
`TOTAL_HIGH`, and `BOM_MEDIUM_LINE` handling so Slack is still notified when
Medium is the highest severity for BOM findings, while preserving the existing
skip behavior for truly clean results. Use the notification section in
`vuln-scan-images.yaml` and the surrounding severity totals to locate the fix.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Enterprise
Run ID: 0fffeead-b317-4b17-a418-72db37ad7bc8
📒 Files selected for processing (1)
.github/workflows/vuln-scan-images.yaml
Summary
Extends
vuln-scan-images.yamlto cover the full ~82-image upstream set (sourced frommake bom) at Medium+ severity, and adds agen-vex-drafts.pyscript that auto-generatesunder_investigationOpenVEX draft statements for new findings and opens a PR for human triage.Closes #1473.
Parent epic: #739.
Changes
.github/workflows/vuln-scan-images.yamlThree new jobs added after the existing
scanjob;notifyandcleanupupdated.bom-listmake bom, extracts all container image refs frombom.cdx.jsonviajq, outputs a JSON array. New components are picked up automatically — no hand-maintained list.scan-bombom-listseverity-cutoff: medium,only-fixed: false(upstream images — escalation/VEX feeds rather than in-tree fixes).max-parallel: 10to cap bandwidth and registry rate-limit risk. Per-job upload:.txtsummary +.json(full Grype output for VEX) +.ref(raw image ref).vex-draftscan-bombom-scan-*artifacts, runsgen-vex-drafts.py, opens a PR against.openvex.jsonwhen new(vuln-id, product-purl)pairs are found. Skipped cleanly whenbom-listfails or produces an empty list.notify(updated)scan+scan-bomscan-bombeing skipped does not block the NVIDIA notification.cleanup(updated)notify+vex-draft.github/scripts/gen-vex-drafts.py(new)(vuln-name, product-purl)pairs from.openvex.json— idempotent, never duplicates.*.ref/*.jsonpair frombom-scan-results/.under_investigationstatement with an OCI PURL keyed to the exact image ref.under_investigationleaves Grype reporting findings; a human must update status tonot_affected/affected/fixedwith evidence before suppression takes effect..openvex.json, incrementsversion, stampstimestampandtooling.new_count=Nto$GITHUB_OUTPUT; the workflow gates thecreate-pull-requeststep onnew_count > 0.Success criteria (from #1473)
make bom— no hand-maintained image listunder_investigationOpenVEX draft statements without auto-suppressingTesting
yamllint -c .yamllint.yaml— 0 warningspython3 -m py_compile gen-vex-drafts.py— cleannew_count=0,.openvex.jsonunchangedpython3 -c "import yaml; ..."— allneeds:chains correct