ec-cve-check¶
Inspect the CVE scan results that Enterprise Contract (EC) actually gates on
for Konflux-built container images, and test whether an EC policy exception
can be safely removed. The clair-scan Tekton task emits two outputs from a
single scan: SCAN_OUTPUT (RHSA-filtered counts shown in the build UI,
often 0 for Python/Go) and REPORTS (the full Clair report stored as an OCI
blob — the exact data EC's cve.cve_blockers rule evaluates at release time).
This gap is why a build can look clean while EC blocks the release. This plugin
reads the REPORTS data directly.
The workflow is auth-then-scan: setup-auth.sh pulls the tenant-wide
components-namespace-pull secret (covering every repo under
quay.io/redhat-user-workloads/<tenant>/*) and, optionally, the cosign public
key for offline use. inspect-clair-cves.sh then resolves the image to a
digest, verifies the cosign attestation, extracts the REPORTS OCI blob, and
prints a severity-sorted CVE table (or --json for scripting). Package names
reveal the data source — CSAF/VEX feed entries, RPM sub-packages (deduplicate
by CVE ID), and pip/Python findings from GHSA/PYSEC (watch for PEP 440 local-
version false positives on downstream-patched packages).
Beyond inspection, the skill supports layer decomposition (diff a base
image scan against a product image scan to separate inherited from
product-introduced CVEs) and ECP exception testing. Exception removal can
be validated two ways: the preferred local EC CLI path (build a modified policy
with cve.cve_blockers removed, reduce the snapshot to a single component, run
ec validate image in ~30s) or a cluster PipelineRun via
test-exception-removal.sh (slower, subject to Kueue quota). A key caveat runs
through both paths: only push-pipeline snapshots (on-push) carry CVE scan
data — pull/MR snapshots skip Clair entirely, so cve.cve_blockers silently
passes on them (a false pass, not a real result).
Plugin Details
- Version: 0.1.0
- Author: jrusz
- License: Apache-2.0
- Category: DevOps & CI/CD
- Repository: jrusz/ec-cve-check
- Tags: cve enterprise-contract konflux clair security release-gating cosign
Skills¶
| Skill | Description | Invocable |
|---|---|---|
/ec-cve-check |
Inspect CVE scan results and test ECP exception removal for Konflux-built images |
Installation¶
Claude Code
/plugin install ec-cve-check@opendatahub-skills
OpenAI Codex — add the marketplace, then enable ec-cve-check from the /plugins browser:
codex plugin marketplace add opendatahub-io/skills-registry
Architecture¶
A single guided skill (/ec-cve-check) that orchestrates three bundled bash
scripts plus an optional local EC CLI path. It is fully deterministic — no LLM
or agent calls. Inspection (setup-auth.sh, inspect-clair-cves.sh) and the
local EC CLI path are read-only and never modify images, snapshots, or ECP
policies. The one exception is the cluster PipelineRun path
(test-exception-removal.sh), which submits (creates) a temporary Enterprise
Contract PipelineRun on the cluster to validate exception removal.
Data flow for inspection:
1. setup-auth.sh <tenant> — oc extracts components-namespace-pull
(dockerconfigjson) to /tmp/clair-auth/config.json; --key also exports
the cosign public key from openshift-pipelines/public-key.
2. inspect-clair-cves.sh <image> [--json]:
- skopeo inspect resolves a tag to a sha256: digest (digests pass
through unchanged);
- cosign verify-attestation --type slsaprovenance fetches the SLSA
provenance attestation;
- a Python pass walks buildConfig.tasks for the clair-scan task,
collecting REPORTS blob digests, the SCAN_OUTPUT summary, and the source
repo from IMAGES_PROCESSED;
- skopeo copy pulls each REPORTS OCI blob (falling back to the
redhat-user-workloads source repo when the released repo lacks it);
- a final Python pass expands package_vulnerabilities, dedups by
(package, version, CVE), sorts by severity, and prints a table or JSON.
Exception testing shares the same auth. The local EC CLI path edits the ECP
YAML in memory (drop cve.cve_blockers, add builtin.image.accessible to
excludes to silence registry-auth noise), reduces the snapshot to one
component, and runs ec validate image offline (--ignore-rekor). The cluster
path submits an EC PipelineRun from konflux-ci/build-definitions and polls up
to 10 minutes, then greps the verify pod logs for [Violation] cve.cve_blockers
to report the unique blocking CVE IDs and affected images.
Reference docs ship alongside the skill: references/cve-scanning-architecture.md
(the two-output SCAN_OUTPUT/REPORTS split and source-repo links) and
references/ecp-exception-testing.md (result interpretation, push-vs-pull
snapshots, granular per-CVE exceptions, and PipelineRun troubleshooting).