- API_CLI_REFERENCE.md, INSTALL_GUIDE.md, quickstart.md, architecture/integrations.md, dev/DEV_ENVIRONMENT_SETUP.md, integrations/LOCAL_SERVICES.md: reflect real-service wiring. - docs/modules/**: module dossier updates across the modules touched by SPRINT_20260415_001..007 + SPRINT_20260416_003..017 + SPRINT_20260417_018..024 + SPRINT_20260418_025 + SPRINT_20260419_026. - docs/features/checked/web/**: update feature notes where UI changed. - docs/qa/feature-checks/runs/web/evidence-presentation-ux/: QA evidence artifacts. - docs/setup/**, docs/technical/**: align with setup wizard contracts. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6.3 KiB
6.3 KiB
SBOM Service Architecture
Scope: canonical SBOM projections, ledger history, lineage, registry-source state, and durable SBOM event backlogs consumed by Console, Policy, Concelier, Graph, and Findings.
1) Mission and boundaries
- Serve deterministic, tenant-scoped SBOM projections and ledger history.
- Accept scanner-produced SBOMs or operator-supplied SPDX/CycloneDX uploads.
- Own append-only SBOM versioning, lineage edges, retention, and related audit state.
- Do not perform scanning itself and do not author policy verdicts.
2) Runtime layout
- Host:
src/SbomService/StellaOps.SbomService - Persistence:
src/SbomService/__Libraries/StellaOps.SbomService.Persistence - Tests:
src/SbomService/__Tests/StellaOps.SbomService.Persistence.Tests
2.1 Durable state
- Canonical PostgreSQL tables now include:
sbom.projections,sbom.catalog,sbom.component_neighborssbom.entrypoints,sbom.orchestrator_sources,sbom.orchestrator_controlsbom.ledger_versions,sbom.ledger_audit,sbom.analysis_jobs,sbom.watermarkssbom.lineage_edgessbom.version_events,sbom.asset_events,sbom.inventory_events,sbom.resolver_candidatessbom.registry_sources,sbom.registry_source_runs
- Startup migrations are embedded in the persistence assembly and run automatically on host startup.
2.2 Truthful unsupported surface
- The live durable runtime no longer fabricates dependency-path data from in-memory seeds.
- Until a durable dependency-path backend exists:
GET /sbom/pathsreturns501 sbom_paths_unsupported- dependency-path portions of
GET /sbom/contextreturn501 sbom_paths_unsupported POST /internal/sbom/inventory/backfillreturns501 sbom_inventory_backfill_unsupportedPOST /internal/sbom/resolver-feed/backfillreturns501 sbom_resolver_feed_backfill_unsupported
3) Primary APIs
POST /sbom/uploadvalidates and normalizes SPDX 2.3/3.0 or CycloneDX 1.4-1.7 and appends a new ledger version.GET /sbom/versions?artifact=...returns the durable timeline for an artifact.GET /sbom/ledger/history,/point,/range,/diff,/lineageexpose ledger and lineage state.GET /console/sbomsreads the durable catalog view.GET /components/lookup?purl=...reads the durable component-neighbor view.POST /entrypointsandGET /entrypointsmanage tenant-scoped entrypoint overrides.GET /sboms/{snapshotId}/projectionreturns the stored Link-Not-Merge projection.
4) Internal APIs
GET /internal/sbom/eventsreturns durablesbom.version.createdbacklog state.POST /internal/sbom/events/backfillreplays stored projections into the durable event backlog.GET /internal/sbom/asset-eventsreturns durablesbom.asset.updatedbacklog state.GET /internal/jobengine/sourcesandPOST /internal/jobengine/sourcesmanage ingest sources.GET /internal/jobengine/controlandPOST /internal/jobengine/controlmanage pause/throttle/backpressure state.GET /internal/jobengine/watermarksandPOST /internal/jobengine/watermarksmanage durable watermarks.GET /internal/sbom/resolver-feedandGET /internal/sbom/resolver-feed/exportexpose the persisted resolver candidate store.GET /internal/sbom/ledger/auditandGET /internal/sbom/analysis/jobsexpose durable ledger audit and analysis job history.POST /internal/sbom/retention/pruneapplies durable retention policy.
5) Ingestion and ledger behavior
- Uploads are normalized into deterministic component lists before persistence.
- Each artifact keeps an append-only chain of
SbomLedgerVersionrecords. - Audit entries are written for ledger mutations.
- Analysis jobs are persisted immediately when upload-triggered work is queued.
- Lineage edges are persisted for parent, base-image, and shared-build relationships.
- Retention pruning removes old versions while preserving auditability.
6) Events and derived state
- Durable event backlogs are stored in:
sbom.version_eventssbom.asset_eventssbom.inventory_eventssbom.resolver_candidates
sbom.version.createdandsbom.asset.updatedare canonical durable outputs today.- Inventory and resolver feeds remain durable stores, but automatic rebuild of those feeds is blocked on the missing durable dependency-path backend.
7) Registry source management
- Registry source definitions and run history are durable PostgreSQL state.
RegistrySourcestores URL, filters, trigger mode, auth references, and tenant ownership.RegistrySourceRunstores discovery/scan counts, trigger metadata, and completion state.
8) Determinism and offline posture
- Stable ordering, UTC timestamps, and canonical hashing are required for all read models and ledger state.
- The service remains offline-friendly: no external calls are required for persistence or replay.
Testingis the only supported environment for fixture-backed or in-memory fallback runtime composition when PostgreSQL is intentionally absent.- Development, staging, and production runtimes now fail startup if
SbomService:PostgreSQLis not configured.
9) Configuration
SbomService:PostgreSQL:ConnectionStringenables the live durable runtime.SbomService:PostgreSQL:Schemaoptionally overrides the default schemasbom.SbomService:Ledger:*controls retention:MaxVersionsPerArtifactMaxAgeDaysMinVersionsToKeep
SbomService:RegistryHttp,SbomService:ScannerHttp, andSbomService:RegistrySourceQueryconfigure registry discovery and scan emission behavior.
10) Proof status
- Durable host build:
StellaOps.SbomServicebuilds cleanly with PostgreSQL-backed canonical stores. - Durable persistence proof:
StellaOps.SbomService.Persistence.Testscovers ledger, event store, registry-source persistence, and repository-backed timeline rebuild across service instances.
11) Open gaps
- Add a durable dependency-path backend so
/sbom/paths, dependency-path context assembly, and inventory/resolver feed backfill can leave truthful501mode. - Normalize the shared contract surface further if the persistence assembly keeps absorbing host-owned types.
12) Related docs
docs/modules/sbomservice/ledger-lineage.mddocs/modules/sbomservice/byos-ingestion.mddocs/modules/sbomservice/retention-policy.mddocs/modules/sbomservice/api/projection-read.md