feat(cli): honor CycloneDX VEX suppressions in the --fail-on gate#51
Open
dmchaledev wants to merge 1 commit into
Open
feat(cli): honor CycloneDX VEX suppressions in the --fail-on gate#51dmchaledev wants to merge 1 commit into
dmchaledev wants to merge 1 commit into
Conversation
A CycloneDX vulnerability may carry an `analysis.state` (VEX) declaring the product is `not_affected` or the finding a `false_positive`. Previously the parser ignored this field, so such a vulnerability was reported as a new CVE and could fail the `--fail-on` CI gate — a false-positive build break that undermines the gate's trustworthiness, which is exactly what VEX exists to prevent. - parser: capture `vulnerabilities[].analysis.state` (lowercased) on CVEEntry - cli: exclude `not_affected`/`false_positive` CVEs from gateFailures via a new exported `isSuppressed` helper; actionable states (exploitable, in_triage, resolved, none) and CVEs without VEX still gate as before - reporter: annotate new CVEs with `(VEX: <state>)` in text and markdown so a suppressed-but-listed CVE explains why the gate passed - types: document the new optional `analysisState` field - tests: parser extraction/lowercasing, gate suppression, isSuppressed, reporter - docs: note VEX-aware gating in the README Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GxwABuKnNRN53T7QmVqe4d
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
CycloneDX vulnerabilities can carry an
analysis.state(VEX) declaring that the product isnot_affectedby a CVE, or that a finding is afalse_positive. Today the parser ignores this field entirely, so such a vulnerability is reported as a plain "new CVE" and — since #49 landed the--fail-ongate — it fails the CI build.That is a false-positive gate break: the SBOM's own author has already assessed and documented that the product is not impacted, yet the gate stops the pipeline anyway. Suppressing exactly this case is the entire purpose of VEX, so a gate that ignores it is a real blind spot for a tool marketed as "perfect for CI/CD gates."
No open issue or PR touches VEX /
analysis.state— this is orthogonal to all in-flight work (which is about component/purl keying, CVSS extraction, ordering, license/hash diffs, etc.).Reproduction (before this change)
A CVE the SBOM marks
not_affectedstill exits3under--fail-on critical:What changed
src/parser.ts): capturevulnerabilities[].analysis.state, lowercased, ontoCVEEntry.analysisState.src/cli.ts):gateFailuresnow excludesnot_affected/false_positiveCVEs before applying the policy, via a new exportedisSuppressed(v)helper. Actionable states (exploitable,in_triage,resolved,none) and CVEs with no VEX still gate exactly as before.src/reporter.ts): new CVEs are tagged(VEX: <state>)in text and markdown, so a suppressed-but-listed CVE explains why the gate passed — the audit trail stays complete.src/types.ts): documents the new optionalanalysisStatefield.Behavior after this change
The same CVE without the
analysisblock still exits3, as before.Why it's safe / self-contained
not_affected/false_positivechange behavior; everything else is untouched. SBOMs without VEX (the current fixtures) behave identically.Tests
npm run typecheck,npm run lint, andnpx vitest runall pass — 45 tests (was 38). Added coverage:analysis.state; absent block →undefinedgateFailuresignores suppressed CVEs underanyand severity thresholds, while still failing on real +in_triagefindingsisSuppressedtrue only fornot_affected/false_positive(VEX: …)tag in text and markdown🤖 Generated with Claude Code
https://claude.ai/code/session_01GxwABuKnNRN53T7QmVqe4d
Generated by Claude Code