save checkpoint

This commit is contained in:
master
2026-02-14 09:11:48 +02:00
parent 9ca2de05df
commit e9aeadc040
1512 changed files with 30863 additions and 4728 deletions

View File

@@ -0,0 +1,42 @@
# Per-Layer SBOM Export API
## Module
Scanner
## Status
VERIFIED
## Description
Per-layer SBOMs stored as individual CAS artifacts with API endpoints to retrieve layer-specific SBOMs (GET /scans/{id}/layers, GET /scans/{id}/layers/{digest}/sbom with format param), content negotiation, immutable caching (ETag, Cache-Control), and CLI commands (stella scan layer-sbom, stella scan recipe).
## Implementation Details
- **API Endpoints**:
- `src/Scanner/StellaOps.Scanner.WebService/Endpoints/LayerSbomEndpoints.cs` - `LayerSbomEndpoints` with `GET /scans/{id}/layers` (list layers) and `GET /scans/{id}/layers/{digest}/sbom` (retrieve per-layer SBOM with format negotiation)
- `src/Scanner/StellaOps.Scanner.WebService/Endpoints/ScanEndpoints.cs` - Scan endpoints integrating per-layer SBOM access
- **Layer SBOM Service**:
- `src/Scanner/StellaOps.Scanner.WebService/Services/ILayerSbomService.cs` - `ILayerSbomService` interface for layer SBOM operations
- `src/Scanner/StellaOps.Scanner.WebService/Services/LayerSbomService.cs` - `LayerSbomService` manages per-layer SBOM retrieval with content negotiation (SPDX, CycloneDX) and immutable caching
- `src/Scanner/StellaOps.Scanner.WebService/Services/SurfacePointerService.cs` - `SurfacePointerService` tracks surface-level pointers for layer SBOMs
- **Layer SBOM Composition**:
- `src/Scanner/__Libraries/StellaOps.Scanner.Emit/Composition/LayerSbomComposer.cs` - Composes per-layer SBOMs
- `src/Scanner/__Libraries/StellaOps.Scanner.Emit/Composition/SpdxLayerWriter.cs` - SPDX format layer SBOM writer
- `src/Scanner/__Libraries/StellaOps.Scanner.Emit/Composition/CycloneDxLayerWriter.cs` - CycloneDX format layer SBOM writer
## E2E Test Plan
- [ ] Call `GET /scans/{id}/layers` and verify a list of container layers with digests and sizes is returned
- [ ] Call `GET /scans/{id}/layers/{digest}/sbom?format=spdx` and verify a valid SPDX SBOM is returned for the specific layer
- [ ] Call `GET /scans/{id}/layers/{digest}/sbom?format=cyclonedx` and verify a valid CycloneDX SBOM is returned
- [ ] Verify ETag and Cache-Control headers are set for immutable caching of per-layer SBOMs
- [ ] Verify content negotiation via Accept header works as an alternative to the format query parameter
- [ ] Verify requesting a non-existent layer digest returns 404
---
## Verification
| Check | Result |
|-------|--------|
| Tier 0 - Source files exist | PASS |
| Tier 1 - Build + code review | PASS |
| Tier 2 - Integration tests | PASS |
| Verified | 2026-02-13T18:10:00Z |