Add unit tests and implementations for MongoDB index models and OpenAPI metadata

- Implemented `MongoIndexModelTests` to verify index models for various stores.
- Created `OpenApiMetadataFactory` with methods to generate OpenAPI metadata.
- Added tests for `OpenApiMetadataFactory` to ensure expected defaults and URL overrides.
- Introduced `ObserverSurfaceSecrets` and `WebhookSurfaceSecrets` for managing secrets.
- Developed `RuntimeSurfaceFsClient` and `WebhookSurfaceFsClient` for manifest retrieval.
- Added dependency injection tests for `SurfaceEnvironmentRegistration` in both Observer and Webhook contexts.
- Implemented tests for secret resolution in `ObserverSurfaceSecretsTests` and `WebhookSurfaceSecretsTests`.
- Created `EnsureLinkNotMergeCollectionsMigrationTests` to validate MongoDB migration logic.
- Added project files for MongoDB tests and NuGet package mirroring.
This commit is contained in:
master
2025-11-17 21:21:56 +02:00
parent d3128aec24
commit 9075bad2d9
146 changed files with 152183 additions and 82 deletions

View File

@@ -0,0 +1,66 @@
# Excititor Advisory-AI evidence APIs (projection + chunks)
> Covers the read-only evidence surfaces shipped in Sprints 119120: `/v1/vex/observations/{vulnerabilityId}/{productKey}` and `/v1/vex/evidence/chunks`.
## Scope and determinism
- **Aggregation-only**: no consensus, severity merging, or reachability. Responses carry raw statements plus provenance/signature metadata.
- **Stable ordering**: both endpoints sort by `lastSeen` DESC; pagination uses a deterministic `limit`.
- **Limits**: observation projection default `limit=200`, max `500`; chunk stream default `limit=500`, max `2000`.
- **Tenancy**: reads respect `X-Stella-Tenant` when provided; otherwise fall back to `DefaultTenant` configuration.
- **Auth**: bearer token with `vex.read` scope required.
## `/v1/vex/observations/{vulnerabilityId}/{productKey}`
- **Response**: JSON object with `vulnerabilityId`, `productKey`, `generatedAt`, `totalCount`, `truncated`, `statements[]`.
- **Statement fields**: `observationId`, `providerId`, `status`, `justification`, `detail`, `firstSeen`, `lastSeen`, `scope{key,name,version,purl,cpe,componentIdentifiers[]}`, `anchors[]`, `document{digest,format,revision,sourceUri}`, `signature{type,keyId,issuer,verifiedAt}`.
- **Filters**:
- `providerId` (multi-valued, comma-separated)
- `status` (values in `VexClaimStatus`)
- `since` (ISO-8601, UTC)
- `limit` (ints within bounds)
- **Mapping back to storage**:
- `observationId` = `{providerId}:{document.digest}`
- `document.digest` locates the raw record in `vex_raw`.
- `anchors` contain JSON pointers/paragraph locators from source metadata.
Headers:
- `Excititor-Results-Truncated: true|false`
- `Excititor-Results-Total: <int>`
## `/v1/vex/evidence/chunks`
- **Query params**: `vulnerabilityId` (required), `productKey` (required), optional `providerId`, `status`, `since`, `limit`.
- **Response**: **NDJSON** stream; each line is a `VexEvidenceChunkResponse`.
- **Chunk fields**: `observationId`, `linksetId`, `vulnerabilityId`, `productKey`, `providerId`, `status`, `justification`, `detail`, `scopeScore` (from confidence or signals), `firstSeen`, `lastSeen`, `scope{...}`, `document{digest,format,sourceUri,revision}`, `signature{type,subject,issuer,keyId,verifiedAt,transparencyRef}`, `metadata` (flattened additionalMetadata).
- **Headers**: same truncation/total headers as projection API.
- **Streaming guidance (SDK/clients)**:
- Use HTTP client that supports response streaming; read line-by-line and JSON-deserialize per line.
- Treat stream as unbounded list up to `limit`; do not assume array brackets.
- Back-off or paginate by adjusting `since` or narrowing providers/statuses.
## `/v1/vex/attestations/{attestationId}`
- **Purpose**: Lookup attestation provenance (supplier ↔ observation/linkset ↔ product/vulnerability) without touching consensus.
- **Response**: `VexAttestationPayload` with fields:
- `attestationId`, `supplierId`, `observationId`, `linksetId`, `vulnerabilityId`, `productKey`, `justificationSummary`, `issuedAt`, `metadata{}`.
- **Semantics**:
- `attestationId` matches the export/attestation ID used when signing (Resolve/Worker flows).
- `observationId`/`linksetId` map back to evidence identifiers; clients can stitch provenance for citations.
- **Auth**: `vex.read` scope; tenant header optional (payloads are tenant-agnostic).
## Error model
- Standard API envelope with `ValidationProblem` for missing required params.
- `scope` failures return `403` with problem details.
- Tenancy parse failures return `400`.
## Backwards compatibility
- No legacy routes are deprecated by these endpoints; they are additive and remain aggregation-only.
## References
- Implementation: `src/Excititor/StellaOps.Excititor.WebService/Program.cs` (`/v1/vex/observations/**`, `/v1/vex/evidence/chunks`).
- Telemetry: `src/Excititor/StellaOps.Excititor.WebService/Telemetry/EvidenceTelemetry.cs` (`excititor.vex.observation.*`, `excititor.vex.chunks.*`).
- Data model: `src/Excititor/StellaOps.Excititor.WebService/Contracts/VexObservationContracts.cs`, `Contracts/VexEvidenceChunkContracts.cs`.