Skip to content

p-rog/ai-cve-validator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AI CVE Validator

Intelligent CVE validation for Red Hat container images and OpenShift CoreOS.

Tired of chasing false positives from security scanners? This project delivers a set of AI agent skills and Claude Code commands that give you accurate, context-aware CVE validation for Red Hat container images — backed by official Red Hat security data, not third-party guesswork.

What it does

  • Validates CVEs against container images using official build-time and release-time SPDX SBOMs from container attestations — no synthetic SBOMs, no third-party tools manipulating the data. If no official SBOM is available, agents can optionally fall back to syft to generate an analyzed SBOM and continue validation on a best-effort basis (analyzed SBOMs have lower quality and accuracy than official build-time or release-time SBOMs and this is clearly noted in the report)
  • Checks Red Hat VEX and CSAF files directly from security.access.redhat.com to determine if a CVE truly affects your image or is a false positive
  • Verifies CoreOS (RHCOS) in specific OCP releases — extracts the full RPM package list and validates against CVE metadata and VEX data with RHEL EUS stream awareness
  • Resolves RHSA advisories when scanners report advisory IDs instead of CVEs
  • Provides clear remediation steps including layered product relationships — if a CVE affects an RPM in your container image, a dedicated agent checks whether newer images with the fixed RPM have already been published
  • Detects VEX data gaps where Red Hat hasn't assessed a specific component, and recommends reporting to secalert@redhat.com

Why use it

Most SCA scanners flag every CVE that matches a package name, producing noisy reports full of false positives. This project does what scanners can't — it reads the actual SBOM attestation, checks Red Hat's official VEX statements, understands product stream versioning (RHEL EUS vs. latest), and tells you whether a reported CVE is a true positive, false positive, or uncertain. When a fix exists, it points you to the exact RHSA advisory and, for container images, checks if a rebuilt image is already available in the registry.

Project status

This project is actively evolving. The core validation pipeline is functional and tested against real CVEs and Red Hat images. New features (CoreOS support, RHSA advisory input, VEX discrepancy detection) are being added regularly. Contributions and feedback are welcome.

Quick reference

See REFERENCE.md for a complete list of all skills, commands, scripts, and their options.

Two approaches

Interactive (Claude Code skills & commands) — AI agent skills that run inside Claude Code. You provide a CVE ID and image reference, the agent orchestrates the validation pipeline, and delivers a structured security report. Best for interactive investigation and security review.

Fully automated (CrewAI framework) — A Python-based multi-agent pipeline that runs without human interaction. Designed for CI/CD integration, batch scanning, and automated security workflows. Uses the same helper scripts and validation logic as the interactive approach.


Architecture

Both approaches use a shared set of helper scripts for deterministic data fetching, with the AI agent handling all interpretation and matching logic.


Approach 1: Claude Skill + Command

Files

Artifact Path Invocation
Skill Claude/.claude/skills/container-cve-validator/SKILL.md Via /skills dialog or natural language request
Command Claude/.claude/commands/container-cve-validator.md /container-cve-validator <CVE-ID> <IMAGE_REFERENCE>
CoreOS Skill Claude/.claude/skills/coreos-cve-validator/SKILL.md Via /skills dialog or natural language request
CoreOS Command Claude/.claude/commands/coreos-cve-validator.md /coreos-cve-validator <CVE-ID> <OCP-VERSION>

Description

Markdown-based prompt files that instruct Claude to act as a security validator directly inside the Claude CLI. No Python or application code — Claude uses its built-in terminal tool to execute shell commands. The skill and command share identical logic; they differ only in how they receive inputs and how they are triggered.

Skill vs Command:

  • The skill is designed for agentic and multi-step workflows where Claude autonomously decides to apply it, or it can be selected via the /skills UI dialog. Input is taken from conversation context.
  • The command is designed for explicit, predictable, user-triggered invocation via /container-cve-validator. Arguments are parsed directly from the command line ($ARGUMENTS).

Prerequisites

Tool Purpose
regctl Remote image metadata inspection — ~1.5s per image vs ~5s for skopeo
cosign SBOM extraction (attestation and build-time)
jq JSON parsing

All tools are verified before execution begins. Missing tools cause an immediate stop with installation guidance.

Validation Pipeline

Input Validation

  • CVE ID validated against CVE-YYYY-NNNNN format
  • Image reference parsed into registry, name, tag/digest components
  • Image metadata fetched remotely via regctl image config (no pull needed, ~1.5s vs ~5s for skopeo) to extract: cpe (product CPE), name (public VEX name), vendor, maintainer, org.opencontainers.image.created — labels at .config.Labels in regctl output. version/release labels are intentionally excluded — they contain base image metadata, not the actual container tag
  • Registry ownership validated via vendor/maintainer labels — non-Red Hat images stopped immediately
  • Mirrored images (e.g., on quay.io) accepted if vendor/maintainer confirms Red Hat; canonical registry.redhat.io reference recorded for VEX matching
  • Digest-based references resolved to human-readable tags via image labels; digest form retained for SBOM commands

Step 1 — CVE Reconnaissance

  • Queries MITRE CVE API with HTTP status handling (404, non-200, empty affected)
  • For Go ecosystem: additionally queries OSV API to resolve GO-YYYY-NNNN ID, then fetches full module-level data from vuln.go.dev (module path, semver ranges, affected symbols)
  • GitHub Security Advisories accepted as secondary source only if they carry an official CVE ID

Step 2 — SBOM Extraction and Package Verification

  • Attempt A: Release-time attestation SBOM via cosign download attestation --predicate-type=spdx
    • Iterates all payload lines, selects SPDX envelope by predicateType, prefers most recent by creationInfo.created
    • Detects image index SBOMs (SPDXRef-image-index): extracts linux/amd64 digest from checksumValue/referenceLocator PURL and re-fetches with architecture-specific digest
  • Attempt B: Build-time SBOM via cosign download sbom (fallback)
    • Same image index detection and re-fetch logic applies
  • Container tag/digest extraction: reads the pkg:oci/ PURL from the SBOM image entry to obtain the correct tag(s) and digest — one image can have multiple tags. For digest-based input the tag is resolved from the PURL; for tag-based input the digest is collected as additional reference. version/release labels are never used for tag reconstruction.
  • Package matching: PURL-based search across all ecosystems (pkg:rpm, pkg:golang, pkg:pypi, pkg:npm, etc.); also checks SPDX relationships to identify non-RPM packages linked to parent RPM deliverables
  • Version comparison: ecosystem-aware (RPM EVR ordering, Go semver, PyPI/npm per CVE versions[]); three outcomes: vulnerable / patched / inconclusive

Step 3 — Red Hat VEX Validation

  • Fetches CSAF VEX from security.access.redhat.com/data/csaf/v2/vex/[YEAR]/[cve-id].json
  • Generic blanket detection: VEX files containing only "All currently supported Red Hat products" under cpe:/a:redhat represent an unanalysed placeholder — treated as equivalent to no VEX coverage
  • Two-level product_tree matching: products identified by CPE, components by PURL in product_identification_helper; matched via product_tree.relationships[]
    • 4a: Exact match on image cpe label + name label
    • 4b: Name-only match across CPE versions — surfaces patches available in newer product streams without applying their status to the scanned image
    • 4c: No match → potential VEX data gap
  • Status extraction from vulnerabilities[].product_status[]: fixed, known_affected, known_not_affected, under_investigation
  • Remediation details from vulnerabilities[].remediations[]: all RHSA advisory URLs for vendor_fix; no_fix_planned / none_available for affected products
  • Not-affected justification from vulnerabilities[].flags[].label: verbatim flag (e.g., component_not_present, vulnerable_code_not_present)
  • Severity from vulnerabilities[].threats[]: product-scoped first, global fallback, explicit N/A if absent
  • Parent RPM patch status (triggered when SBOM identifies a non-RPM package linked to a parent RPM via SPDX relationship):
    • Searches VEX product_tree.relationships[] for the parent RPM across ALL product streams, focusing on RHEL CPE patterns (cpe:/o:redhat:enterprise_linux:*, cpe:/a:redhat:rhel_eus:*, etc.)
    • If parent RPM is fixed in RHEL: extracts RHSA advisory URLs and records that the container must be rebuilt to include the patched RPM
    • Key distinction: a patched RPM in RHEL does NOT mean the container is fixed — the container image must be rebuilt before it is no longer affected

Step 4 — Newer Image Availability Scan

Trigger: RPM or parent-RPM vulnerable package AND a fixed RPM version + RHSA release date are known from Step 3. Skipped for non-RPM packages with no parent RPM, or when no fixed version is known.

  • Extracts the image repository (strips tag/digest from the scanned image reference)
  • Uses regctl tag ls + xargs -P 15 parallel date checks to efficiently find all image tags built after the scanned image's created timestamp — ISO 8601 string comparison, 15 concurrent regctl processes
  • Filters out sha*, source, and latest tags; deduplicates by digest
  • For each newer candidate: downloads its SBOM and checks whether the fixed RPM version (or higher) is present using RPM EVR ordering
  • Compares the candidate image's cpe label against the scanned image's CPE:
    • Same CPE → patched image in the same product stream
    • Different CPE → patched image in a newer/different product stream (upgrading changes the product stream)
  • Reports all patched images found, or records "no patched image released yet" if none found

Step 5 — Final Report with VEX Data Gap Assessment

Three data gap conditions evaluated before writing the report:

Condition Trigger Status
A VEX exists, specific entries present, component fully absent (4c) + package in SBOM + version vulnerable Potentially vulnerable — Red Hat VEX data gap
B VEX returns 404 + package in SBOM + version vulnerable Potentially vulnerable — No Red Hat VEX data
C VEX exists but contains only generic blanket statement + package in SBOM + version vulnerable Potentially vulnerable — Generic Red Hat VEX, CVE not individually reviewed

All three gap conditions recommend reporting to secalert@redhat.com with CVE ID, image reference, and SBOM evidence.

Output Formats

Both the skill and command support single-scan and batch-scan modes, three output formats, and two verbosity modes:

# Single scan
/container-cve-validator [--format markdown|json|csv] [--output full|summary] <CVE-ID> <IMAGE_REFERENCE>

# Batch scan from CSV file
/container-cve-validator [--format markdown|json|csv] [--output full|summary] --file <PATH>
Flag Values Default Description
--format markdown, json, csv markdown Controls the output serialisation format
--output full, summary full Controls Markdown verbosity; not applicable to json or csv
--file file path CSV file for batch scanning; mutually exclusive with positional CVE ID and image reference
  • --output full — complete Markdown report with all nine sections (default)
  • --output summary — condensed Markdown: executive summary paragraph + numbered recommended actions only
  • --format json — machine-readable JSON object with 6 structured fields (see schema below); a JSON array when used with --file
  • --format csv — CSV with a single header row followed by one data row per scan
  • --file PATH — CSV input file with one cve_id,image_ref pair per line; optional cve_id header row is skipped; blank lines and # comment lines are ignored

Batch file format:

cve_id,image_ref
CVE-2023-38039,registry.redhat.io/ubi9/ubi:latest
CVE-2025-15467,registry.redhat.io/ubi8/ubi:8.10

Batch file validation (all checks run before any scan starts):

  • UTF-8 encoding; maximum file size 1 MB; maximum 500 entries
  • Each row must have exactly 2 columns; CVE ID must match CVE-YYYY-NNNNN format
  • Image reference must contain only safe characters ([a-zA-Z0-9._/:\-@]) — shell metacharacters are rejected; must include at least one /; maximum 512 characters

JSON / CSV schema (field order matches the intended reading order):

Field Type Description
scanned_image string Fully qualified image reference
cve_id string CVE identifier
status true_positive | false_positive | uncertain Whether the image is affected (see semantics below)
status_source vex_confirmed | sbom_analysis | vex_not_affected How the status was determined
vendor_patch_available "true" | "false" | "" Whether a fixed container image is available ("" = unknown or only base RPM patched)
patch_path.advisory_name string Advisory that fixes the container image; "" if no container-level fix
patch_path.advisory_url string URL to the container fix advisory; "" if none
related_rpm_patch.advisory_name string Base RPM advisory (informational — cannot be applied to container directly); "" if none
related_rpm_patch.advisory_url string URL to the RPM advisory; "" if none
recommendation string Concise action for the user (1-2 sentences)

Missing values: JSON uses "" (empty string) — never null. CSV leaves the field empty — never the literal word null.

Status semantics: true_positive = package present in SBOM AND version confirmed vulnerable — regardless of VEX coverage (includes VEX data gap scenarios where SBOM evidence confirms the vulnerability); false_positive = VEX known_not_affected; uncertain = genuinely inconclusive (version comparison failed, under_investigation with no SBOM confirmation).

Status source semantics: vex_confirmed = VEX directly matched the product and stated its status; sbom_analysis = determined from SBOM + CVE metadata (VEX data gap, missing, or generic blanket); vex_not_affected = VEX explicitly says known_not_affected (used only with false_positive).

vendor_patch_available and patch_path refer to container image fixes only. A base RPM patch (e.g., openssl-libs fixed in RHEL) does NOT count — the user cannot apply it to a container image independently. When a base RPM is patched but the container has not been rebuilt, vendor_patch_available is "" (unknown), patch_path is empty, and the RPM advisory goes into related_rpm_patch.

Full Report Sections

## CVE Validation Report
- CVE ID / Image
- Executive Summary
- Image Metadata (registry, vendor, name, CPE, version, build date, SBOM method)
- CVE Details (package, ecosystem, versions, Go module/ID if applicable)
- SBOM Findings (found, installed version, version range verdict, SPDX entry type)
- Red Hat VEX Status (status, severity, CPE match, remediation, RHSA advisories,
                      not-affected justification, patch availability note, caution,
                      upstream patch note)
- Parent RPM Patch Status (parent RPM name, RPM fix status in RHEL, RHSA URLs,
                           container rebuild required flag)
- Newer Image Availability (repository scanned, patched image in same/newer product stream,
                            recommendation)
- VEX Data Gap (gap type, analysis basis, action required)

Helper Scripts

Both approaches (Claude skill/command and CrewAI) use a shared set of standalone Python scripts in scripts/ for all deterministic data-fetching steps. Each script takes CLI arguments, outputs structured JSON to stdout, and handles errors gracefully.

Script Purpose Usage
validate_input.py Validate CVE ID, image reference, and batch CSV files. Classifies registries (registry.redhat.io, quay.io/openshift-release-dev/, etc.) python scripts/validate_input.py --cve CVE-2024-45490 --image registry.redhat.io/ubi9/ubi:latest
fetch_cve_metadata.py Query MITRE CVE API, OSV.dev, and Go vuln DB (conditional). Returns merged affected packages with ecosystem, version ranges, and source python scripts/fetch_cve_metadata.py CVE-2024-45490
fetch_redhat_vex.py Fetch Red Hat CSAF VEX data. Default: deduped summary with all products, CPEs, statuses, and remediation URLs. With --raw: full CSAF JSON python scripts/fetch_redhat_vex.py CVE-2024-45490
download_sbom.py Download SBOM via cosign (attestation first, build-time fallback). Handles image index detection and amd64 re-fetching automatically python scripts/download_sbom.py registry.redhat.io/ubi9/ubi:latest
generate_sbom_syft.py Generate an analyzed SBOM using syft when no official SBOM is available. Same output schema as download_sbom.py python scripts/generate_sbom_syft.py registry.redhat.io/ubi9/ubi-minimal:latest
inspect_image.py Extract image metadata (labels, digest, architecture) via regctl without downloading the image python scripts/inspect_image.py registry.redhat.io/ubi9/ubi:latest
scan_newer_images.py Scan a container image repository for images built after a given date. Returns tags, digests, build dates, CPEs. Uses parallel regctl checks. python scripts/scan_newer_images.py registry.redhat.io/ubi9/ubi --since 2026-01-01T00:00:00Z
fetch_coreos_metadata.py Fetch OCP release info via oc, extract CoreOS RPM list via podman, classify RPMs by source (RHEL/OCP/Fast Datapath), determine RHEL version. Handles both legacy (416.94.202410071428-0) and new (9.6.20260314-0) CoreOS versioning schemes python scripts/fetch_coreos_metadata.py 4.20.17
fetch_rhsa_advisory.py Fetch Red Hat Security Advisory (RHSA) CSAF data and extract CVE references. Used when scanners report RHSA IDs instead of CVE IDs python scripts/fetch_rhsa_advisory.py RHSA-2026:3337

Why scripts? The LLM agent runs one script per step and gets structured JSON back, instead of multiple LLM-to-tool round-trips for curl/cosign/jq commands. This significantly reduces execution time for both approaches — especially CrewAI, where each tool call previously involved a separate LLM reasoning cycle.

Dependencies: All scripts require Python 3 and requests. download_sbom.py requires cosign, generate_sbom_syft.py requires syft, inspect_image.py requires regctl, and fetch_coreos_metadata.py requires oc and podman (plus a pull secret for quay.io/openshift-release-dev/). Each script checks for its tools and returns a clear error if missing.


Approach 2: CrewAI Multi-Agent

Path: CrewAI/cve_ai_validation.py

Description

A Python-based multi-agent framework using CrewAI. Three specialized agents run sequentially, each with a dedicated tool and role. The LLM backend is Claude accessed via Google Vertex AI.

Prerequisites

  • Python virtual environment with CrewAI dependencies (see setup below)
  • ANTHROPIC_VERTEX_PROJECT_ID environment variable set
  • ANTHROPIC_VERTEX_REGION environment variable (optional, defaults to us-east5)
  • Google Cloud Application Default Credentials (gcloud auth application-default login)

Setup

cd CrewAI
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Usage

Run from within the activated venv:

cd CrewAI
source .venv/bin/activate
export CREWAI_TELEMETRY_OPT_OUT=true
python cve_ai_validation.py <CVE-ID> <IMAGE_REFERENCE>

Or without activating:

CrewAI/.venv/bin/python CrewAI/cve_ai_validation.py <CVE-ID> <IMAGE_REFERENCE>

Output Formats

python cve_ai_validation.py [--format markdown|json|csv] [--output full|summary] <CVE-ID> <IMAGE_REFERENCE>
python cve_ai_validation.py [--format markdown|json|csv] [--output full|summary] --file <PATH>
  • --format markdown --output full — complete Markdown report (default)
  • --format markdown --output summary — condensed Markdown: executive summary + recommended actions
  • --format json — machine-readable JSON with 6 fields; JSON array for batch; report agent skips Markdown generation entirely to save tokens and time
  • --format csv — single header row + one data row per scan
  • --file PATH — batch CSV input; same format and validation rules as the Claude skill/command

JSON/CSV schema is identical to the Claude skill/command — see the schema table above.

Architecture

Six sequential agents, each with dedicated tools:

run_security_scan(cve_id, image_ref, output_mode="full", fmt="markdown")
        │
        ▼
  [Agent 1] Input Validator & Image Inspector
        tools: validate_input, inspect_image_metadata
        │
        ▼
  [Agent 2] CVE Reconnaissance Specialist
        tools: fetch_cve_metadata
        │
        ▼
  [Agent 3] SBOM Analyst & Package Verifier
        tools: download_sbom, generate_sbom_syft
        │
        ▼
  [Agent 4] VEX Security Analyst
        tool: fetch_vex
        │
        ▼
  [Agent 5] Container Image Update Scanner
        tools: list_newer_image_tags, inspect_image_metadata,
               download_sbom
        │
        ▼
  [Agent 6] Report Writer
        (no tools — synthesis only)
        │
        ▼
  format_output() → Markdown (full/summary) | JSON | CSV

Full architecture detail: see CrewAI/README.md

LLM Configuration

  • Model: claude-sonnet-4-6 (default — configurable via ANTHROPIC_VERTEX_MODEL env var)
  • Provider: Google Vertex AI (ANTHROPIC_VERTEX_PROJECT_ID — same backend as local Claude CLI)
  • Region: ANTHROPIC_VERTEX_REGION (defaults to us-east5)
  • Temperature: 0.2
  • Requires: GCP project with Vertex AI enabled and Application Default Credentials

Strengths

  • Clear separation of concerns across 6 specialised Python agents
  • 8 focused tools cover all data retrieval; agents handle reasoning
  • Full parity with the Claude skill validation logic, including output format options
  • Unit-testable Python tools
  • Easily extensible — add agents, swap models, integrate into pipelines
  • Programmatic entry point: run_security_scan(cve_id, image_ref, output_mode, fmt)

Weaknesses

  • Higher setup complexity (Python environment, pip dependencies)
  • Requires regctl and cosign on PATH (same as skill)
  • More verbose output (6 agents × verbose=True)

Comparison Summary

Dimension Claude Skill Claude Command CrewAI
Language Markdown (prompt) Markdown (prompt) Python
LLM Access Anthropic API (Claude CLI key) Anthropic API (Claude CLI key) Google Vertex AI (ANTHROPIC_VERTEX_PROJECT_ID)
Invocation Autonomous / /skills dialog /container-cve-validator <args> python cve_ai_validation.py <args>
Agent structure Single prompt, sequential steps Single prompt, sequential steps 6 dedicated Python agents
Input source Conversation context $ARGUMENTS (CLI args) CLI args via argparse
Batch scanning --file PATH (CSV) --file PATH (CSV) --file PATH (CSV)
Output formats Markdown, JSON, CSV Markdown, JSON, CSV Markdown, JSON, CSV
Output verbosity --output full / --output summary --output full / --output summary --output full / --output summary
Image validation Full (CPE, registry, digest, mirror) Full (CPE, registry, digest, mirror) Full (CPE, registry, digest, mirror)
SBOM parsing PURL + SPDX relationships, multi-ecosystem PURL + SPDX relationships, multi-ecosystem PURL + SPDX relationships, multi-ecosystem
Image index handling Yes (re-fetch with amd64 digest) Yes (re-fetch with amd64 digest) Yes (re-fetch with amd64 digest)
Go vuln DB Yes (OSV + vuln.go.dev) Yes (OSV + vuln.go.dev) Yes (OSV + vuln.go.dev)
Version comparison Yes (RPM EVR, semver, PyPI/npm) Yes (RPM EVR, semver, PyPI/npm) Yes (RPM EVR, semver, PyPI/npm)
VEX data gap detection Yes (3 conditions + secalert) Yes (3 conditions + secalert) Yes (3 conditions + secalert)
VEX product stream mismatch Yes (newer CPE version detection) Yes (newer CPE version detection) Yes (newer CPE version detection)
CoreOS (RHCOS) support Yes (/coreos-cve-validator) Yes (/coreos-cve-validator) Not yet
RHSA advisory input Yes (auto-detected, resolved to CVEs) Yes (auto-detected, resolved to CVEs) Not yet
Dependencies regctl, cosign, Python 3, requests regctl, cosign, Python 3, requests regctl, cosign, Python 3, requests, CrewAI packages
Portability High (two Markdown files) High (two Markdown files) Medium (Python env)
Testability Low Low High (unit-testable tools)
Programmatic integration No No Yes (run_security_scan())
Permission prompts Yes — per command Yes — per command None (Python subprocess)
Setup complexity Minimal Minimal Moderate

Permission Prompts (Claude Skill and Command)

The Claude skill and command execute all external tools (regctl, cosign, curl, jq) via Claude Code's terminal tool. By default, Claude Code will prompt for approval before each individual command, which can be disruptive during a scan that runs dozens of commands.

The CrewAI approach has no prompts — all commands run via Python subprocess calls, completely outside Claude Code's permission system.

Avoiding prompts for the skill and command

Pre-approve the required commands in your Claude Code settings to eliminate per-command prompts. Add the following to .claude/settings.json (user-level) or .claude/settings.local.json (project-level):

{
  "allowedTools": [
    "Bash(regctl:*)",
    "Bash(cosign:*)",
    "Bash(curl:*)",
    "Bash(jq:*)"
  ]
}

With these rules in place, Claude Code will execute all scan commands automatically without interruption. You can also configure this interactively using the /update-config skill inside Claude Code.


Shared Pipeline Logic

All implementations follow the same core security validation sequence:

Container Image Pipeline

  1. CVE Reconnaissance — Query cveawg.mitre.org to identify affected packages, ecosystems, and version ranges.
  2. SBOM Analysis — Extract the container image SBOM via cosign. Prefer release-time attestation SBOM; fall back to build-time SBOM; fall back to syft-generated SBOM.
  3. Red Hat VEX Check — Query security.access.redhat.com/data/csaf/v2/vex/ for the official Red Hat exploitability status.
  4. Report — Produce a structured Markdown security report.

CoreOS (RHCOS) Pipeline

  1. CVE Reconnaissance — Same as container pipeline.
  2. CoreOS Metadata — Fetch OCP release info via oc, extract RPM package list via podman, classify RPMs by source (RHEL/OCP/Fast Datapath).
  3. RPM Matching — Search CoreOS RPMs for the affected package, compare installed version.
  4. Red Hat VEX Check — Check both RHCOS component under OCP CPE and specific RPM under RHEL/OCP CPE. Detect VEX discrepancies (RHCOS entry missing but RPM assessed).
  5. Report — CoreOS-specific report with RPM source classification and VEX discrepancy assessment.

RHSA Advisory Input

When a scanner reports an RHSA advisory ID instead of a CVE ID, the fetch_rhsa_advisory.py script resolves it to individual CVE IDs, which then feed into either pipeline above.

All implementations share the same helper scripts in scripts/ for deterministic data-fetching steps.


Detailed Reports

Implementation Report
Claude Skill + Command This file (root REPORT.md)
CrewAI Multi-Agent CrewAI/README.md

Next Steps

  • Test all three implementations against real CVEs and Red Hat images
  • Build a shared regression test harness comparing outputs across implementations
  • Consider a CI/CD pipeline integration using the CrewAI run_security_scan() function
  • Adding MCP server to allow futher integration with other ai agents and tools.

Execution Speed: Claude Command vs CrewAI

The Claude command approach is significantly faster than CrewAI for the same scan. This is an architectural trade-off, not a bug.

Why CrewAI is slower

Multiple LLM API calls over the network. The Claude command is one continuous Claude session — the LLM reads the skill prompt and executes all steps. CrewAI makes 6+ separate API calls to Google Vertex AI (one per agent, often more since agents reason → call tool → reason again about the result). Each network round trip adds latency on top of inference time.

Agent reasoning overhead per task. Each CrewAI agent doesn't just call a tool — it reasons before calling, receives the result, then reasons again about whether to call another tool. A single agent task can trigger 3-5 LLM calls internally.

Growing context with each agent. Agent 6 (Report Writer) receives the full output of all 5 prior agents as context. By that point thousands of tokens are fed into each LLM call, increasing inference time on every step.

Agent 5 (Newer Image Scanner) is particularly expensive. It potentially calls list_newer_image_tags (parallel regctl, fast) then downloads SBOMs via cosign for multiple newer image candidates — each cosign call can take 10-30 seconds, multiplied by several tags.

Sequential execution by design. All 6 agents run sequentially. Each waits for the previous to fully complete before starting.

Approximate timing comparison

Step Claude command CrewAI (with scripts) CrewAI (old, inline tools)
Input validation + image inspect ~2s ~5-10s ~15-30s
CVE recon (MITRE + OSV + Go) ~3s ~5-15s ~20-40s
SBOM download + analysis ~10-20s ~15-30s ~30-60s
VEX validation ~3s ~5-15s ~20-40s
Newer image scan ~20-60s ~30-90s ~60-180s
Report generation ~5s ~20-40s ~20-40s
Total ~45s-2 min ~2-4 min ~5-10 min

The fundamental trade-off

Claude Skill / Command CrewAI
Speed Fast — one LLM session Slow — 6+ API round trips
Requires Claude Code Yes No
Human in the loop Yes (interactive) No (fully automated)
Programmatic integration No Yes (run_security_scan())
Output formats Markdown, JSON, CSV Markdown, JSON, CSV
Testability Low High (unit-testable tools)
Extensibility Edit Markdown Add agents/tools in Python

CrewAI's value is not speed — it is full automation without a human in the loop, programmatic integration into CI/CD pipelines, and independently unit-testable components. For interactive use where speed matters, the Claude command is the better choice.

About

AI-powered CVE validation for Red Hat container images and OpenShift CoreOS using official SBOMs and VEX data

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages