| name | cve-vex-assess |
| description | Use this skill to determine VEX (Vulnerability Exploitability eXchange) justification when a CVE is not present in scan results. Auto-detects three justification types. Cases requiring human judgment are flagged for manual review. Writes result to autofix-output/cve-vex-result.json. |
| allowed-tools | Bash Read Write |
| context | fork |
| model | sonnet |
Skill: CVE VEX Assess
When a CVE scan returns "absent" or "informational", determine the appropriate
VEX justification. Three of the five CSAF justification types can be
auto-detected; the remaining two require human judgment.
Step 1: Check — Component not Present
The package is not declared in any dependency manifest.
cd "${REPO_DIR}/${BUILD_LOCATION:-.}"
FOUND_IN_MANIFEST=""
case "$LANG" in
go) FOUND_IN_MANIFEST=$(grep -Fi -- "${PACKAGE}" go.mod 2>/dev/null) ;;
node) FOUND_IN_MANIFEST=$(grep -Fi -- "${PACKAGE}" package.json package-lock.json 2>/dev/null) ;;
python) FOUND_IN_MANIFEST=$(grep -rFi -- "${PACKAGE}" requirements*.txt setup.py pyproject.toml 2>/dev/null) ;;
esac
if [ -z "$FOUND_IN_MANIFEST" ]; then
JUSTIFICATION="component_not_present"
EVIDENCE="Package '${PACKAGE}' not found in any dependency manifest"
fi
Step 2: Check — Vulnerable Code not Present
Package is in the manifest but at a version that is already patched.
Determine the fixed version by checking the CVE advisory (NVD, GitHub Advisory
Database, or language-specific advisory). For Go, check the govulncheck output
which lists the fixed version. For Node.js, check npm audit output. For
Python, check pip-audit output or the PyPI advisory.
if [ -z "$JUSTIFICATION" ] && [ -n "$FOUND_IN_MANIFEST" ] && [ -n "$CVE_FIXED_VERSION" ]; then
HIGHER=$(printf '%s\n' "$INSTALLED_VERSION" "$CVE_FIXED_VERSION" | sort -V | tail -1)
if [ "$HIGHER" = "$INSTALLED_VERSION" ]; then
JUSTIFICATION="vulnerable_code_not_present"
EVIDENCE="Package '${PACKAGE}' at version ${INSTALLED_VERSION} >= fixed version ${CVE_FIXED_VERSION}"
fi
fi
Step 3: Check — Vulnerable Code not in Execute Path (Go only)
govulncheck reports a module as "Informational" when it is in the dependency
tree but the vulnerable symbol is not called.
if [ -z "$JUSTIFICATION" ] && [ "$LANG" = "go" ]; then
if printf '%s' "$SCAN_OUTPUT" | grep -q "Informational" && \
printf '%s' "$SCAN_OUTPUT" | grep -A5 "Informational" | grep -Fqi -- "${PACKAGE}"; then
JUSTIFICATION="vulnerable_code_not_in_execute_path"
EVIDENCE="govulncheck found module in dep tree but vulnerable symbol is not called"
fi
fi
Step 4: Determine final assessment
| # | Justification | Auto-detectable? |
|---|
| 1 | Component not Present | Yes |
| 2 | Vulnerable Code not Present | Yes |
| 3 | Vulnerable Code not in Execute Path | Yes (Go only) |
| 4 | Vulnerable Code cannot be Controlled by Adversary | No — human judgment |
| 5 | Inline Mitigations already Exist | No — human judgment |
If none of checks 1-3 matched:
if [ -z "$JUSTIFICATION" ]; then
JUSTIFICATION="needs_human_review"
EVIDENCE="Auto-detection inconclusive — requires human judgment (types 4 or 5)"
fi
Step 5: Write output
Create autofix-output/ if it doesn't exist. Write autofix-output/cve-vex-result.json:
{
"cve_id": "CVE-2025-68121",
"repo": "opendatahub-io/models-as-a-service",
"branch": "main",
"justification": "component_not_present",
"justification_label": "Component not Present",
"evidence": "Package 'urllib3' not found in any dependency manifest",
"auto_detected": true,
"package": "urllib3",
"installed_version": null,
"fixed_version": "2.2.3",
"timestamp": "2026-04-27T12:00:00Z"
}
Caller contract
The orchestrator reads auto_detected:
true → post Jira comment with VEX justification (never auto-close the issue)
false → document in artifacts, flag for manual review
Gotchas
- Only 3 of 5 VEX justification types can be auto-detected; types 4 (Vulnerable Code cannot be Controlled by Adversary) and 5 (Inline Mitigations already Exist) require human judgment
sort -V requires GNU coreutils (standard in CI containers, not available on macOS by default — install via brew install coreutils)
- Never auto-close Jira issues — leave closing to the human reviewer, even when a VEX justification is clear-cut