Roadmap

Product roadmap for BOMHort — v0.8.0 contract, the v0.9.0 vulnerability register, the v1.0 freeze with the CRA dashboard, and what comes after.

Vision

BOMHort is transitioning from a single-instance SBOM visualization tool into an enterprise-grade, multi-cluster Software Supply Chain Security platform. Phase 1 (foundation, auth, multi-cluster model, push ingestion) shipped in v0.4–v0.7.

The roadmap is organised around one hard deadline — the v1.0.0 schema and API freeze — and one regulatory fact: the EU Cyber Resilience Act’s vulnerability-reporting obligations are in force since 2026-09-11, and customers already ask for a CRA-grade vulnerability register. The CRA scope therefore moved into 1.0 (re-plan 2026-09-25), and 1.0 is reached in three steps:

ReleaseDueTheme
v0.8.0 ✅2026-10-31Contract — MCP server, project aggregation, source_repo fix, values.yaml shape, CVE ids, CSV export, license provenance
v0.9.02026-11-30Vulnerability register — CVSS, CWE, KEV, EPSS, remediation record, SLA due dates (#414)
v1.0.02027-01-31Freeze + CRA dashboard — readiness score, MTTR, auditor report bundle, crypto-library inventory, versioned docs
v1.1.02027-04-30Automation, fleet & cryptography — VEXViper, fleet views, OSV mirror, attestations, CBOM
v1.2.02027-07-31Analytics — Scorecard, Lottery Factor, SBOM diff, tree view, blast radius, enriched export

Two rules drive sequencing:

  • If it can’t be back-filled, it lands before 1.0; if it’s additive, it lands after. The register work is additive and lands before 1.0 for market reasons, not contract reasons — the Schema Change Register says which is which.
  • Issues raised by the consumer side ship first. #398 and #399 came from someone building on BOMHort; they opened v0.8.0.

Phase 1: Foundation & Security ✅

Q1–Q2 2026 · Complete. Production-ready with real security requirements.

StatusIssueDescription
✅#131 Cluster-aware data modelcluster column on all core tables (migration 012).
✅#134 API AuthenticationService token + API key modes. Gate for all write operations.
✅#137 Enhanced health checks/readyz, /livez for K8s probes.
✅#139 Headless modeAPI-only deployment without Angular UI.
✅#59 Expose API externallyHelm Ingress template + TLS.
✅#8 Project List ViewGroup SBOMs by project.
✅#144 SBOM DownloadDownload SBOM JSON from the platform.
✅#55 CycloneDX SupportParse CycloneDX 1.4+ SBOMs.
✅#37 Version Skew DetectionCross-org dependency consistency.
✅#132 / #133 Cluster endpointsGET /api/v1/clusters, per-cluster stats and SBOM lists.
✅#135 SBOM Upload (Push Model)POST /api/v1/sboms/upload from CI/CD pipelines.
✅#398 Project-centric read modelGET /api/v1/projects/{name} + sub-resources, de-duplicated counts; the project identity rule is contract. Shipped in v0.8.0.
🟡#136 Enhanced CORSFunctionally done (POST on upload, X-API-Key). Remaining bits (CORS_ALLOW_CREDENTIALS, configurable methods) are additive → v1.1.0.

Schema wave 014–022 — complete: document_store (#256), namespace/project (#138, #57), source_repo/source_ref (#332), VEX provenance (#334), VEX SBOM scope (#350), OSV aliases, VEX product_ref, document_version, tags (#357). 023–026 followed in v0.8.0; the v0.9.0 register work starts at 027.

Delivered beyond the roadmap: Global Search, Package Search, in-toto attestation unwrapping, protobom parsing backend, license resolution via GitHub + npm + NuGet with license-text classification, SPDX license expression evaluation (#402), dark mode, white-label theming, Prow chat-ops (#405).


Phase 2: The road to 1.0

Oct 2026 – Jan 2027 · Theme: Freeze a contract that an external consumer has already exercised (#399), and ship a CRA-grade vulnerability register inside the frozen surface rather than bolting it on after.

v0.8.0 — Contract ✅

StatusIssueDescription
✅#399 BOMHort MCP serverFive read-only tools over the REST API (cmd/mcp-server), no ClickHouse credentials. stdio by default; Streamable HTTP refuses to start without a bearer token and a non-wildcard Origin allow-list. See MCP Server.
✅#58 Aggregated SBOM ViewThe SBOM Explorer reads by project, not by document — same de-duplication as #398.
✅#355 source_repo on real SBOMsdocumentNamespace fallback, release/tag/commit URL handling, CycloneDX distribution. Existing rows need a re-parse.
✅#397 existingConfigMapLicense policy and exceptions mount from an externally managed ConfigMap.
✅#391 Seed job removedA leftover seedJob block fails helm template with a message naming the alternatives.
✅#392 ClickHouse floor24.8 LTS, pinned by digest; CI runs every query against 24.8 and 24.12.
✅#344 E + IProject stats read only the selected projects’ SBOMs; apiGateway.queryLimits.* bounds gateway queries (on by default). A–D, F–H stay post-1.0.
✅#412 CVE id + aliasescve_id and aliases on findings, VEX statements and search; lookups by any alias.
✅#266 CSV exportGET /api/v1/reports/vulnerabilities?format=csv, streamed, formula-injection safe.
✅#439 License provenancedeps.dev/Packagist/PyPI resolvers, unapproved category, per-package license source (migration 024). See License Resolution.

v0.9.0 — Vulnerability register

Due 2026-11-30. The #414 umbrella: CRA Annex I Part II made queryable — per finding and per deployed version: CVE, CWE, CVSS, EPSS, KEV status, remediation status, due date, and a timestamp proving it is current.

StatusIssueMigrationDescription
🔲#408 CVSS score, vector, version (incl. v4)027Score is computed in osvutil today and discarded. Backfill from osv_json.
🔲#409 CWE ids027From OSV database_specific.cwe_ids. Enables crypto CWE filters.
🔲#410 CISA KEV status028_create_kev_catalogDaily feed; the public signal for “actively exploited” (CRA Art. 14, 24 h). Brings a due date.
🔲#64 EPSS scores029_create_epss_scoresPulled forward from v1.2.0; shares the refresher plumbing with KEV.
🔲#413 VEX action statement as remediation record030action_statement_timestamp on vex_statements.
🔲#411 Remediation SLA policynoneremediation-policy.json → derived due_date, overdue, remediation_status. No write API.
🔲#414 Register umbrella—Docs page, last_refreshed_at on export and dashboard, final CSV column list.

v1.0.0 — Freeze + CRA dashboard

Due 2027-01-31, after a four-week soak of v0.9.0 on the CNCF instance.

StatusIssueDescription
🔲#141 CRA compliance dashboardReadiness score per project/cluster, computed from what v0.9.0 stores. #140/#143 become additional inputs in v1.1.0, not prerequisites.
🔲#7 CVE fix time (MTTR)031_create_vulnerability_resolutions. Stretch — drops to v1.1.0 if the soak needs the time.
🔲#62 Auditor report bundleCSV + JSON bundle with a manifest. PDF only after the library decision; not a blocker.
🔲#419 Crypto-library inventoryFrom existing SBOMs by PURL match (032); no CBOM needed.
🔲#145 Versioned documentationShips with the tag.
🔲Migration guide + values.yaml reviewEvery key added since v0.7: mcp.*, existingConfigMap, seedJob removal, apiGateway.queryLimits.*, image pin, kev.*, epss.*, remediationPolicy.*, cryptoLibraries.*.

What v1.0 means

  • API contract frozen — no endpoint removals or response shape changes without v2.0
  • ClickHouse schema stable — no ORDER BY or column-type changes; ADD COLUMN … DEFAULT and new tables remain allowed
  • Helm values stable — existing values.yaml keys won’t be renamed
  • Supported ClickHouse floor — 24.8 LTS, covered by CI (#392) ✅
  • Support policy active — current release + 2 previous minors receive security patches (see Support Policy)
  • A CRA-grade vulnerability register is exportable per deployed version, and a readiness score is computed from it

All v0.x releases are development milestones and may contain breaking changes between minor versions — read the release notes before upgrading.


Phase 3: Automation, Fleet & Cryptography

v1.1.0 · due 2027-04-30.

Epic #338 — Automated VEX generation (VEXViper)

VEXViper is an out-of-tree Go sidecar: it reads findings via the REST API, gathers evidence, asks a configurable LLM or rule engine, and uploads validated OpenVEX back. The correctness blockers (#332, #335, #355) have all landed.

StatusIssueDescription
🔲#336 Idempotent VEX upload + job statusContent-hash dedupe; GET /api/v1/uploads/{job_id}. New table 03x_create_upload_jobs.
🔲#333 Incremental listing + vex_status=missing?since=&cursor= on /sboms. Query-only.
🔲#334 Provenance UIAutomated vs. human badge, status_notes, ?vex_source=.
🔲#337 Outbound webhooksHMAC-signed sbom.ingested, findings.updated, vex.applied, upload.rejected.

Fleet operations

StatusIssueDescription
🔲#138 Namespace filtering (API + UI)?namespace= on list endpoints, namespace chips.
🔲#267 → #176 Cluster PickerQuery-param filter first (help wanted), then navbar dropdown.
🔲#140 Workload vulnerability summaryImage → posture; additional #141 input.
🔲#57 Per-project policiesLicense policies, severity thresholds, exception scopes per project.
🔲#136 CORS (remaining)CORS_ALLOW_CREDENTIALS, configurable methods/headers.
🔲#60 Local OSV mirrorOffline / air-gapped; KEV and EPSS feeds get the same treatment.
🔲#143 In-toto Witness integration03x_create_attestations, signature verification; additional #141 input.

Cryptography — #420 (CBOM)

StatusIssueDescription
🔲#415 CycloneDX 1.6 crypto assets03x_create_crypto_assets.
🔲#416 Cryptographic inventoryAlgorithms, protocols, certificates, keys per project/fleet.
🔲#417 Crypto policy + exceptionscrypto-policy.json, BSI TR-02102 / NIST SP 800-131A example profiles.
🔲#418 PQC readinessquantum_vulnerable / hybrid / pqc classification, readiness % per project.

Phase 4: Analytics

v1.2.0 · due 2027-07-31. CRA scoring left this phase for 1.0; what remains is prioritisation and dependency-health depth.

StatusIssueDescription
🔲#255 Enriched SBOMs + enriched downloadOverlay on the #256 originals; companion VEX; in-toto re-sign.
🔲#254 protobom/storage schema evaluationResearch; informs #255. Not a rewrite of sbom_packages.
🔲#38 SBOM DiffDependency tree divergence between versions.
🔲#56 Dependency Tree ViewHierarchical visualization of transitive chains.
🔲#63 Blast Radius SearchVersion-constrained impact analysis.
🔲#61 OpenSSF ScorecardUpstream project health per dependency.
🔲#82 Lottery FactorSingle-maintainer risk detection.
🔲#268 Official ClickHouse operatorBreaking values.yaml change → v2.0 candidate.

Schema Change Register

Everything that touches db/migrations/ or a frozen response shape. The authoritative register — including the “needs pre-1.0?” reasoning per row — is the one in ROADMAP.md; check it, upstream main and open pull requests before claiming a number. After 1.0, ORDER BY and column-type changes are never allowed; ADD COLUMN … DEFAULT and new tables are fine at any time.

MigrationIssueChangePre/Post 1.0
012_add_cluster_column#131ADD COLUMN cluster✅ shipped
013_create_registry_license_cache#330New table✅ shipped
014_create_document_store#256New table✅ shipped (pre)
015_add_namespace_project_columns#138, #57ADD COLUMN namespace, project (core tables + document_store)✅ shipped (pre)
016_add_source_columns#332ADD COLUMN source_repo, source_ref (sboms + ingestion_queue)✅ shipped (pre)
017_add_vex_provenance#334ADD COLUMN author, role, tooling, status_notes✅ shipped (pre)
018_add_vex_sbom_scope#350ADD COLUMN sbom_id on vex_statements + target_sbom_id on ingestion_queue — VEX scoped to its SBOM✅ shipped (pre)
019_add_vulnerability_aliases—ADD COLUMN aliases on vulnerabilities (GHSA ↔ CVE); VEX matches by alias✅ shipped (pre)
020_add_vex_product_ref—ADD COLUMN product_ref on vex_statements (VEX rescue pass)✅ shipped (pre)
021_add_document_version—ADD COLUMN document_version on sboms✅ shipped (pre)
022_add_sbom_tags#357ADD COLUMN tags on sboms + ingestion_queue✅ shipped (pre)
023_add_project_parent—ADD COLUMN parent on sboms/ingestion_queue, root_purl, supplier on sboms (project groups)✅ shipped (pre)
024_add_package_license_sources#439ADD COLUMN package_license_sources on sbom_packages — where each license came from or why it is missing (License Resolution)✅ shipped (pre)
025_add_dependency_depth—ADD COLUMN package_depths on sbom_packages, dependency_depth on vulnerabilities (direct vs. transitive)✅ shipped (pre)
026_add_queue_retry_after—ADD COLUMN retry_after on ingestion_queue (defer jobs on a GitHub rate limit)✅ shipped (pre)
—#335Row semantics of /sboms/{id}/vulnerabilities✅ shipped (pre, API)
—#177cluster in SBOMListItem✅ shipped (pre, API)
—#398De-duplicated project counts; project identity rule is contract✅ shipped (pre, API)
—#399, #397, #391, #392, #344-Imcp.*, existingConfigMap, seedJob removed, ClickHouse image pin, apiGateway.queryLimits.*✅ shipped (pre, Helm values)
—#412, #266cve_id + aliases on findings; CSV export endpoint✅ shipped (pre, API)
—#411remediation-policy.json; derived due_date/overdue, no storagepre (v0.9.0, values)
—#141, #62CRA readiness score; report bundlepre (v1.0.0, API)
027_add_vulnerability_cvss_cwe#408, #409CVSS score/vector/version and CWE IDs on vulnerabilitiespre (v0.9.0)
028_create_kev_catalog#410New tablepre (v0.9.0)
029_create_epss_scores#64New tablepre (v0.9.0)
030_add_vex_action_statement_timestamp#413ADD COLUMN action_statement_timestamp on vex_statementspre (v0.9.0)
031_create_vulnerability_resolutions#7New tablepre (v1.0.0, stretch)
032_create_crypto_libraries#419New table (or MV over sbom_packages)pre (v1.0.0)
03x_create_package_index_mv#344-C/D/EMV + skip indexespost
03x_create_upload_jobs#336New tablepost
03x_create_attestations#143New tablepost
03x_create_crypto_assets, 03x_create_crypto_compliance#415, #417New tablespost (v1.1.0)
03x_*#61, #82, #255, #60New tablespost
—#268Operator swapv2.0

Dependency Graph

PRE-1.0 contract:
#398 ✅ ──┬── #58 ✅ (Aggregated SBOM View)                      v0.8.0
          └── #399 ✅ (MCP: get_project) ── post-1.0: write tools

REGISTER (#414):
#412 ✅ (cve_id/aliases) ── #410 (KEV, matched by alias) ──┐
#408 (CVSS) ─────────────────────────────────────────────┼── #411 (SLA due date; KEV due date overrides) ──┐
#409 (CWE) ──────────────────────────────────────────────┤                                                  ├── #141 (CRA score)  v1.0.0
#64  (EPSS) ─────────────────────────────────────────────┤                                                  ├── #62  (report bundle)
#413 (VEX action statement) ─────────────────────────────┘                                                  └── #7   (MTTR)
#266 ✅ (CSV) ── grows with every row above ── #62

CRYPTO (#420):
#419 (library inventory, SBOM-only)                         v1.0.0
#415 (CBOM ingest) ── #416 (inventory) ── #417 (policy) ── #418 (PQC)   v1.1.0
                                                 └── #409 (CWE-327 filter on the register)

VEXVIPER (#338):
#355 ── #336 (idempotent upload) ── #333 (since/cursor) ── #337 (webhooks) ── #334 UI

FLEET:
#131 ── #132/#133 ── #177 ── #267 ── #176
     └── #138 ── #140 ──┐
#143 (Witness) ─────────┴── additional #141 inputs (v1.1.0)

#60 (OSV/KEV/EPSS mirror) ── standalone
#61, #82 ── extend internal/github        #254 ── informs #255        #268 ── v2.0

Prioritization

Why the CRA moved into 1.0

The reporting obligation is in force, and its 24-hour clock for actively exploited vulnerabilities is exactly what KEV status (#410) makes visible. Customers ask for a register now, column by column. Every register item is additive, so this does not break the back-fill rule — it is pre-1.0 because 1.0 is the release adopters evaluate against the CRA.

Why three releases instead of one

One milestone with 21 issues and a tag at the end slips. v0.8.0 kept its October date, v0.9.0 is the self-contained register, and v1.0.0 adds the score on top with a December soak.

Why VEXViper after the register

The register is what VEX statements are written against: #413 fixes what a statement records, #411 defines what “open” means, #410/#64 define what to triage first.

Cluster vs. namespace vs. project

DimensionQuestionExampleCardinality
clusterWhere is it deployed?prod-eu1–50
namespaceWhich team boundary inside the cluster?payments10–500
projectWhat is it / who owns it?payment-service50–5000

All three are LowCardinality(String) DEFAULT '' columns, none in ORDER BY. tags label projects across these dimensions; they do not replace them.


Non-Goals

  • ❌ Custom Kubernetes Operator (Helm + ClickHouse Operator)
  • ❌ In-tree VEX generation / LLM calls (stays in the VEXViper sidecar; the MCP server is a transport)
  • ❌ MCP write tools in 1.0 (read-only by design)
  • ❌ Write APIs for policies or exceptions — license, remediation, crypto (frontend is public)
  • ❌ Per-finding manual status or due dates (status from VEX, due dates from policy)
  • ❌ CBOM generation or crypto scanning (BOMHort consumes CBOMs)
  • ❌ CRA reporting to ENISA/CSIRTs (BOMHort tells you what and when; filing is your process)
  • ❌ Multi-repo split (monorepo is a hard constraint)
  • ❌ Real-time streaming (batch + webhooks is sufficient)
  • ❌ RBAC/multi-tenancy (auth is binary for now)
  • ❌ Full OIDC in BOMHort (upstream proxy responsibility)
  • ❌ Relational rewrite of sbom_packages (#254 informs the overlay only)

Contributing

Want to pick up an issue from the roadmap? Check the Project Board for items in the Todo column. Issues labeled help wanted or good first issue — for example #267 — are especially good for new contributors.

See Development Guide for setup instructions.