Agent Skills: Skill: CVE VEX Assess

>-

UncategorizedID: opendatahub-io/ai-helpers/cve-vex-assess

Install this agent skill to your local

pnpm dlx add-skill https://github.com/opendatahub-io/ai-helpers/tree/HEAD/helpers/skills/cve-vex-assess

Skill Files

Browse the full folder contents for cve-vex-assess.

Download Skill

Loading file tree…

helpers/skills/cve-vex-assess/SKILL.md

Skill Metadata

Name
cve-vex-assess
Description
>-

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.

# Note: sort -V requires GNU coreutils (standard in CI containers; macOS needs `brew install coreutils`)
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