Skip to content

Instantly share code, notes, and snippets.

@ctron
Created August 26, 2026 10:41
Show Gist options
  • Select an option

  • Save ctron/b1093fb1702dc0d0160322df4aa9fd2b to your computer and use it in GitHub Desktop.

Select an option

Save ctron/b1093fb1702dc0d0160322df4aa9fd2b to your computer and use it in GitHub Desktop.
TC-5744: Evaluation of CISA KEV Catalog Integration (PR #2553)

Evaluation: CISA KEV Catalog Integration (PR #2553)

Jira: TC-5744 | PR: guacsec/trustify#2553 | Date: 2026-08-26

Summary

PR #2553 adds integration with CISA's Known Exploited Vulnerabilities (KEV) catalog to Trustify. The KEV catalog is a curated list of ~1,300 CVEs that are actively exploited in the wild, maintained under Binding Operational Directive 22-01. It complements existing data in Trustify:

  • CSAF/VEX (already in Trustify): "Is this product affected by this CVE?"
  • CVSS (already in Trustify): "How severe is this CVE?"
  • KEV (this PR): "Is this CVE being exploited in the wild right now?"

The PR was submitted by Waldemar Kindler (Think Ahead Technologies), their third contribution to the project. It was AI-assisted (Claude Fable 5 co-authored). After a thorough review cycle with rh-jfuller including a full architectural rework, it was merged on 2026-08-18 with "LGTM."

Recommendation

Accept the contribution for a near-future RHTPA release, gated on completing the follow-up work items below. The code is well-structured, follows project conventions, has strong test coverage (91.15% patch, +0.15% project), and the architecture was explicitly shaped by reviewer feedback into a generic, extensible design. The remaining gaps are UX, documentation, and minor hardening -- not fundamental issues.

What's Delivered

Area Status Notes
Database migration Done exploit table, generic (source-qualified), content-derived UUIDv5 PKs
Entity model Done No FK to vulnerability -- ingestion-order independent
Ingestor (KEV loader) Done Format detection, graceful date parsing, empty-set guard
Importer (periodic sync) Done HTTP download, Last-Modified continuation, 64 MiB cap, timeouts
REST API Done GET /v3/exploit, GET /v3/exploit/{id}, pagination, full-text query
Vulnerability details Done exploits array on VulnerabilityDetails response
OpenAPI spec Done Schemas, paths, tags all generated
Tests (unit) Done Creator, loader, model, date serialization
Tests (integration) Done Ingest, idempotency, removal, revision, empty rejection, importer runner
Tests (e2e) Done Hurl tests: upload, retrieve, filter, cross-reference
Bug fix (shared) Done Date column type was bound as text in query framework
Sample data Done Disabled-by-default daily KEV importer preset

Scope: 2,672 lines added, 39 files (20 new), 25 commits.

Architecture Assessment

The contribution follows Trustify conventions well:

  • Generic exploit entity -- not CISA-specific; source column supports future providers (VulnCheck, ExploitDB)
  • Creator pattern -- uses ExploitCreator with batch add/create per CONVENTIONS.md
  • Full-sync semantics -- delete-and-reinsert per source, justified because CISA withdraws and revises entries; protected by empty-set guard against broken downloads
  • JSONB metadata -- source-specific fields (vendor, product, vulnerability name, required action, ransomware use, CWEs) stored in metadata; only universal fields (dates, CVE ID) are promoted columns
  • Content-derived IDs -- UUIDv5 from (source, cve_id) ensures stable API URLs across resyncs
  • No FK to vulnerability -- same pattern as vulnerability.cwes; entries join at query time on cve_id
  • Observability -- instrumented per conventions (not reviewed in detail)

Deviations from standard patterns (all justified in PR discussion):

  1. Full-sync instead of ON CONFLICT DO NOTHING -- necessary because CISA revises and withdraws entries
  2. remediation_due_date as a real column instead of metadata -- needed for efficient date filtering/sorting of BOD deadlines

Follow-Up Work Required for Production

Must-Have (blocking release)

  1. UI integration (TC-5754) -- The feature is API-only. The frontend needs to surface exploit/KEV data. At minimum:

    • Show an "Exploited" indicator on vulnerability details pages
    • Display KEV metadata (date added, remediation deadline, ransomware use)
    • Decision point: Does this need UXD review/mockups, or can engineering implement a reasonable default?
  2. Documentation (TC-5755) -- Only an importer README was added. User-facing documentation is needed:

    • How to enable the KEV importer
    • What the exploit data means and how to interpret it
    • How exploit data relates to existing advisory/vulnerability data
  3. Dedicated exploit permissions (guacsec/trustify#2596) -- The exploit endpoints currently reuse advisory permissions. Exploits are a distinct entity and need their own set of permissions.

Should-Have (target for same or next release)

  1. Vulnerability list filtering (TC-5756) -- Users should be able to filter the vulnerability list to show only CVEs with known exploits. This is the highest-value UX feature -- it answers "which of my vulnerabilities are actively exploited?"

  2. SBOM-level exploit summary (TC-5757) -- Surface how many CVEs in a given SBOM are on the KEV list. This connects exploit intelligence to the user's actual software inventory.

  3. QE test assets and performance testing (TC-5758) -- The contribution includes good automated tests but uses a 3-entry fixture catalog. QE needs:

    • The full CISA KEV catalog (~1,300 entries) as a test dataset to validate real-world behavior end-to-end
    • Performance tests covering ingestion (full-sync cycle: download, parse, delete+reinsert) and query paths (list, filter, vulnerability details with exploits) against the full dataset
    • Manual test scenarios and acceptance criteria for the UI integration
  4. Scalability if the KEV catalog grows -- The implementation assumes a small catalog (~1,300 entries today). The catalog's growth rate is a CISA policy decision and could accelerate. If it grows significantly, the following design choices would need revisiting:

    • Full-sync in a single transaction -- ExploitCreator::create performs an unbatched DELETE FROM exploit WHERE source = ? followed by chunked inserts, all in one transaction. At large row counts this holds locks for an extended period and blocks concurrent API reads.
    • Entire dataset held in memory -- The walker downloads the full catalog into a Vec<u8> (capped at 64 MiB), the loader deserializes all entries at once, and the creator stores them in a BTreeMap then collects into a Vec<ActiveModel> -- so the full dataset is in memory multiple times simultaneously.
    • No delta/incremental sync -- Every sync cycle replaces all entries for the source, even if only one entry changed.

    Not a blocker today, but worth monitoring.

  5. Delta-based sync for the KEV importer (TC-5759) -- The CISA KEV API offers no delta feed, and unlike the git-based importers (which cache previous state and diff), the KEV importer does a full delete+reinsert every cycle. Caching the previous catalog locally and computing a delta client-side would enable targeted upserts and deletes instead of a full replacement.

Risks and Concerns

Risk Severity Mitigation
Full-sync atomicity -- delete+reinsert ~1,300 rows runs inside a transaction; concurrent API reads during sync could see stale/empty data briefly Low Catalog is small; transaction is fast; Last-Modified means syncs are infrequent (daily, skipped if unchanged)
AI-assisted code -- Most commits co-authored by Claude Fable 5 Low Code was thoroughly reviewed by rh-jfuller with 8+ inline comments; full architectural rework was done; 91% test coverage provides safety net
Maintenance burden -- External contributor; ongoing maintenance falls on the team Medium Code follows project conventions closely; architecture was reviewer-directed; Think Ahead is a repeat contributor (3rd PR)
No upload endpoint for exploit catalogs -- KEV catalog requires explicit ?format=cisakev on the advisory upload endpoint; not auto-detected because Format::Advisory only matches CSAF/CVE/OSV Low Importer bypasses this entirely; tracked as guacsec/trustify#2605 / TC-5753
No cascade delete -- Deleting a vulnerability does not delete its exploit entries Low By design (no FK); exploit entries are source-managed via full-sync, not vulnerability-managed
Upstream catalog changes -- CISA could change the JSON schema Low Only catalogVersion field is required for detection; all entry fields except cve_id are optional with graceful degradation
Air-gapped installations (TC-5760) -- The importer downloads the catalog from cisa.gov over HTTPS; air-gapped or network-restricted deployments cannot reach the upstream source Medium Not solved yet. Possible approaches: manual upload via a future POST /api/v3/exploit endpoint (TC-5753), a local mirror, or a configurable source URL pointing to an internal host. Needs consideration before GA.

Decision Points for Leadership

  1. Release timing: Accept for the next RHTPA release (with UI work), or defer to a later release?
  2. UXD involvement: Is a UXD review needed before building the UI, or can engineering proceed with a reasonable default?
  3. Scope of UI work: Minimal (indicator + details panel) vs. comprehensive (filtering, SBOM summary, dashboard integration)?
  4. Test assets: Does QE need to create dedicated test plans, or are the automated tests sufficient for initial release?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment