- 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>
104 lines
6.3 KiB
Markdown
104 lines
6.3 KiB
Markdown
# 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_neighbors`
|
|
- `sbom.entrypoints`, `sbom.orchestrator_sources`, `sbom.orchestrator_control`
|
|
- `sbom.ledger_versions`, `sbom.ledger_audit`, `sbom.analysis_jobs`, `sbom.watermarks`
|
|
- `sbom.lineage_edges`
|
|
- `sbom.version_events`, `sbom.asset_events`, `sbom.inventory_events`, `sbom.resolver_candidates`
|
|
- `sbom.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/paths` returns `501 sbom_paths_unsupported`
|
|
- dependency-path portions of `GET /sbom/context` return `501 sbom_paths_unsupported`
|
|
- `POST /internal/sbom/inventory/backfill` returns `501 sbom_inventory_backfill_unsupported`
|
|
- `POST /internal/sbom/resolver-feed/backfill` returns `501 sbom_resolver_feed_backfill_unsupported`
|
|
|
|
## 3) Primary APIs
|
|
- `POST /sbom/upload` validates 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`, `/lineage` expose ledger and lineage state.
|
|
- `GET /console/sboms` reads the durable catalog view.
|
|
- `GET /components/lookup?purl=...` reads the durable component-neighbor view.
|
|
- `POST /entrypoints` and `GET /entrypoints` manage tenant-scoped entrypoint overrides.
|
|
- `GET /sboms/{snapshotId}/projection` returns the stored Link-Not-Merge projection.
|
|
|
|
## 4) Internal APIs
|
|
- `GET /internal/sbom/events` returns durable `sbom.version.created` backlog state.
|
|
- `POST /internal/sbom/events/backfill` replays stored projections into the durable event backlog.
|
|
- `GET /internal/sbom/asset-events` returns durable `sbom.asset.updated` backlog state.
|
|
- `GET /internal/jobengine/sources` and `POST /internal/jobengine/sources` manage ingest sources.
|
|
- `GET /internal/jobengine/control` and `POST /internal/jobengine/control` manage pause/throttle/backpressure state.
|
|
- `GET /internal/jobengine/watermarks` and `POST /internal/jobengine/watermarks` manage durable watermarks.
|
|
- `GET /internal/sbom/resolver-feed` and `GET /internal/sbom/resolver-feed/export` expose the persisted resolver candidate store.
|
|
- `GET /internal/sbom/ledger/audit` and `GET /internal/sbom/analysis/jobs` expose durable ledger audit and analysis job history.
|
|
- `POST /internal/sbom/retention/prune` applies 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 `SbomLedgerVersion` records.
|
|
- 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_events`
|
|
- `sbom.asset_events`
|
|
- `sbom.inventory_events`
|
|
- `sbom.resolver_candidates`
|
|
- `sbom.version.created` and `sbom.asset.updated` are 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.
|
|
- `RegistrySource` stores URL, filters, trigger mode, auth references, and tenant ownership.
|
|
- `RegistrySourceRun` stores 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.
|
|
- `Testing` is 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:PostgreSQL` is not configured.
|
|
|
|
## 9) Configuration
|
|
- `SbomService:PostgreSQL:ConnectionString` enables the live durable runtime.
|
|
- `SbomService:PostgreSQL:Schema` optionally overrides the default schema `sbom`.
|
|
- `SbomService:Ledger:*` controls retention:
|
|
- `MaxVersionsPerArtifact`
|
|
- `MaxAgeDays`
|
|
- `MinVersionsToKeep`
|
|
- `SbomService:RegistryHttp`, `SbomService:ScannerHttp`, and `SbomService:RegistrySourceQuery` configure registry discovery and scan emission behavior.
|
|
|
|
## 10) Proof status
|
|
- Durable host build: `StellaOps.SbomService` builds cleanly with PostgreSQL-backed canonical stores.
|
|
- Durable persistence proof: `StellaOps.SbomService.Persistence.Tests` covers 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 truthful `501` mode.
|
|
- Normalize the shared contract surface further if the persistence assembly keeps absorbing host-owned types.
|
|
|
|
## 12) Related docs
|
|
- `docs/modules/sbomservice/ledger-lineage.md`
|
|
- `docs/modules/sbomservice/byos-ingestion.md`
|
|
- `docs/modules/sbomservice/retention-policy.md`
|
|
- `docs/modules/sbomservice/api/projection-read.md`
|