|
| 1 | +OpenVEX Vulnerability Triage |
| 2 | +============================ |
| 3 | + |
| 4 | +``scan_components`` (the OSV matcher) produces vulnerability findings, but every |
| 5 | +known CVE then shows up on every run forever — there was no way to record "we |
| 6 | +looked, this one does not affect us" and drop it. VEX (Vulnerability |
| 7 | +Exploitability eXchange) is the standard for exactly that triage signal. This |
| 8 | +authors `OpenVEX <https://openvex.dev>`_ 0.2.0 statements and applies them to |
| 9 | +the scanner's findings. |
| 10 | + |
| 11 | +``not_affected`` / ``fixed`` statements **suppress** a finding; ``affected`` / |
| 12 | +``under_investigation`` **annotate** it with the assessed status. Statements |
| 13 | +join to findings on the vulnerability id *or* any of its aliases, optionally |
| 14 | +scoped to a product. Pure standard library (``hashlib`` + ``json`` + |
| 15 | +``datetime``); imports no ``PySide6``. |
| 16 | + |
| 17 | +Headless API |
| 18 | +------------ |
| 19 | + |
| 20 | +.. code-block:: python |
| 21 | +
|
| 22 | + from je_auto_control import ( |
| 23 | + scan_components, vex_statement, build_vex, apply_vex) |
| 24 | +
|
| 25 | + findings = scan_components(sbom["components"], advisories) |
| 26 | +
|
| 27 | + statements = [ |
| 28 | + vex_statement("CVE-2024-1", "not_affected", |
| 29 | + products=["pkg:pypi/foo"], |
| 30 | + justification="vulnerable_code_not_present"), |
| 31 | + vex_statement("GHSA-bar", "under_investigation"), |
| 32 | + ] |
| 33 | + vex = build_vex(statements, author="security@example.com") |
| 34 | +
|
| 35 | + triaged = apply_vex(findings, vex) |
| 36 | + # CVE-2024-1 (not_affected) dropped; GHSA-bar kept with vex_status set |
| 37 | +
|
| 38 | +``vex_statement`` validates the inputs: ``status`` must be one of |
| 39 | +``VEX_STATUSES`` (``not_affected`` / ``affected`` / ``fixed`` / |
| 40 | +``under_investigation``); a ``not_affected`` statement must carry a |
| 41 | +``justification`` (one of ``VEX_JUSTIFICATIONS``) or an ``impact_statement``. |
| 42 | +``build_vex`` wraps statements in an OpenVEX document (pass an explicit |
| 43 | +``timestamp`` for a reproducible ``@id``). ``apply_vex`` returns the surviving |
| 44 | +findings, each non-suppressed match annotated with ``vex_status``. |
| 45 | + |
| 46 | +Executor command |
| 47 | +---------------- |
| 48 | + |
| 49 | +``AC_apply_vex`` takes ``findings`` and a ``vex`` document (each a list/object |
| 50 | +or a JSON string) and returns ``{findings, count}`` of the survivors. The same |
| 51 | +operation is exposed as the MCP tool ``ac_apply_vex`` and as a Script Builder |
| 52 | +command under **Security**. It chains directly after ``AC_scan_vulns``. |
0 commit comments