Files
git.stella-ops.org/docs/modules/scanner/design/api-ui-surfacing.md
StellaOps Bot 8768c27f30
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Signals DSSE Sign & Evidence Locker / sign-signals-artifacts (push) Has been cancelled
Signals DSSE Sign & Evidence Locker / verify-signatures (push) Has been cancelled
Add signal contracts for reachability, exploitability, trust, and unknown symbols
- Introduced `ReachabilityState`, `RuntimeHit`, `ExploitabilitySignal`, `ReachabilitySignal`, `SignalEnvelope`, `SignalType`, `TrustSignal`, and `UnknownSymbolSignal` records to define various signal types and their properties.
- Implemented JSON serialization attributes for proper data interchange.
- Created project files for the new signal contracts library and corresponding test projects.
- Added deterministic test fixtures for micro-interaction testing.
- Included cryptographic keys for secure operations with cosign.
2025-12-05 00:27:00 +02:00

298 lines
7.1 KiB
Markdown

# API/UI Surfacing for New Metadata (SC7)
Status: Draft · Date: 2025-12-04
Scope: Define API endpoints and UI components for surfacing CVSS v4, CycloneDX 1.7/CBOM, SLSA 1.2, and evidence metadata with deterministic pagination and sorting.
## Objectives
- Expose new metadata fields via REST API endpoints.
- Define UI components for filters, columns, and downloads.
- Ensure deterministic pagination and sorting across all endpoints.
- Support both online and offline UI rendering.
## API Endpoints
### Vulnerability Ratings (CVSS v4 + v3.1)
```http
GET /api/v1/scans/{scanId}/vulnerabilities
```
Response includes dual CVSS ratings:
```json
{
"vulnerabilities": [
{
"id": "CVE-2025-0001",
"ratings": [
{
"method": "CVSSv4",
"score": 8.5,
"severity": "high",
"vector": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:L/VA:N/SC:N/SI:N/SA:N"
},
{
"method": "CVSSv31",
"score": 7.5,
"severity": "high",
"vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N"
}
],
"evidence": {
"source": "concelier:nvd:2025-12-03",
"hash": "b3:eeee1111...",
"proofId": "proof-12345"
}
}
],
"meta": {
"page": {
"cursor": "eyJpZCI6IkNWRS0yMDI1LTAwMDEiLCJzY29yZSI6OC41fQ==",
"size": 100,
"hasMore": true
},
"sort": {
"field": "ratings.CVSSv4.score",
"direction": "desc"
}
}
}
```
### CBOM Services
```http
GET /api/v1/scans/{scanId}/services
```
Response includes CBOM properties:
```json
{
"services": [
{
"name": "api-gateway",
"version": "1.0.0",
"cbom": {
"ingress": "0.0.0.0:8080",
"egress": "https://external-api.example.invalid:443",
"dataClassification": "pii",
"provider": null,
"region": null
}
}
],
"meta": {
"page": {
"cursor": "eyJuYW1lIjoiYXBpLWdhdGV3YXkifQ==",
"size": 100
}
}
}
```
### Source Provenance (SLSA)
```http
GET /api/v1/scans/{scanId}/provenance
```
Response includes SLSA Source Track:
```json
{
"provenance": {
"source": {
"repo": "https://example.invalid/demo",
"ref": "refs/tags/v1.0.0",
"commit": "aaaa...",
"treeHash": "b3:1111..."
},
"build": {
"id": "build-12345",
"invocationHash": "b3:2222...",
"builderId": "https://builder.stellaops.local/scanner"
},
"dsse": {
"hash": "sha256:4444...",
"cas": "cas://provenance/demo/v1.0.0.dsse"
}
}
}
```
### Evidence Lookup
```http
GET /api/v1/evidence/{evidenceHash}
```
Returns evidence details:
```json
{
"evidence": {
"hash": "b3:eeee1111...",
"source": "scanner:binary-analyzer:v1.0.0",
"type": "binary",
"metadata": {
"buildId": "abc123...",
"symbolsHash": "b3:...",
"confidence": 0.95
},
"cas": "cas://evidence/openssl/3.0.0/binary-analysis.json"
}
}
```
## Pagination & Sorting
### Deterministic Cursors
Cursors are base64-encoded tuples of sort keys:
```json
{
"cursor": "base64({\"id\":\"CVE-2025-0001\",\"score\":8.5})",
"decode": {
"primaryKey": "id",
"secondaryKey": "score",
"lastValue": {"id": "CVE-2025-0001", "score": 8.5}
}
}
```
### Sort Fields
| Endpoint | Default Sort | Allowed Fields |
|----------|--------------|----------------|
| `/vulnerabilities` | `ratings.CVSSv4.score desc, id asc` | `id`, `ratings.CVSSv4.score`, `ratings.CVSSv31.score`, `severity` |
| `/components` | `purl asc, name asc` | `purl`, `name`, `version`, `type` |
| `/services` | `name asc` | `name`, `version`, `cbom.dataClassification` |
### Page Size
| Parameter | Default | Min | Max |
|-----------|---------|-----|-----|
| `pageSize` | 100 | 1 | 500 |
## UI Components
### Vulnerability Table Columns
| Column | Source | Sortable | Filterable |
|--------|--------|----------|------------|
| CVE ID | `id` | Yes | Yes (search) |
| CVSS v4 Score | `ratings[method=CVSSv4].score` | Yes | Yes (range) |
| CVSS v4 Severity | `ratings[method=CVSSv4].severity` | Yes | Yes (multi-select) |
| CVSS v3.1 Score | `ratings[method=CVSSv31].score` | Yes | Yes (range) |
| Affected Component | `affects[].ref` | No | Yes (search) |
| Evidence Source | `evidence.source` | No | Yes (multi-select) |
### CBOM Service View
| Column | Source | Sortable | Filterable |
|--------|--------|----------|------------|
| Service Name | `name` | Yes | Yes |
| Ingress | `cbom.ingress` | No | Yes |
| Egress | `cbom.egress` | No | Yes |
| Data Classification | `cbom.dataClassification` | Yes | Yes (multi-select) |
| Provider | `cbom.provider` | Yes | Yes |
| Region | `cbom.region` | Yes | Yes |
### Filters
```typescript
interface VulnerabilityFilters {
severity?: ('critical' | 'high' | 'medium' | 'low')[];
cvssV4ScoreMin?: number;
cvssV4ScoreMax?: number;
cvssV31ScoreMin?: number;
cvssV31ScoreMax?: number;
hasEvidence?: boolean;
evidenceSource?: string[];
affectedComponent?: string;
}
interface ServiceFilters {
dataClassification?: ('pii' | 'internal' | 'public' | 'confidential')[];
hasEgress?: boolean;
provider?: string[];
region?: string[];
}
```
## Download Formats
### Export Endpoints
```http
GET /api/v1/scans/{scanId}/export?format={format}
```
| Format | Content-Type | Deterministic |
|--------|--------------|---------------|
| `cdx-1.7` | `application/vnd.cyclonedx+json` | Yes |
| `cdx-1.6` | `application/vnd.cyclonedx+json` | Yes |
| `spdx-3.0` | `application/spdx+json` | Yes |
| `csv` | `text/csv` | Yes |
| `pdf` | `application/pdf` | Partial* |
*PDF includes timestamp in footer
### CSV Export Columns
```csv
cve_id,cvss_v4_score,cvss_v4_vector,cvss_v31_score,cvss_v31_vector,severity,affected_purl,evidence_hash,evidence_source
CVE-2025-0001,8.5,"CVSS:4.0/...",7.5,"CVSS:3.1/...",high,pkg:npm/example-lib@2.0.0,b3:eeee...,concelier:nvd:2025-12-03
```
## Determinism Requirements
1. **Sort stability**: All sorts use secondary key (usually `id`) for tie-breaking
2. **Cursor encoding**: Deterministic JSON serialization before base64
3. **Timestamps**: UTC ISO-8601, no sub-millisecond precision unless non-zero
4. **Export ordering**: Same ordering rules as API responses
5. **Filter normalization**: Sort filter arrays before query execution
## Offline Support
### Prefetch Manifest
```json
{
"prefetch": {
"vulnerabilities": "/api/v1/scans/{scanId}/vulnerabilities?pageSize=500",
"components": "/api/v1/scans/{scanId}/components?pageSize=500",
"services": "/api/v1/scans/{scanId}/services",
"provenance": "/api/v1/scans/{scanId}/provenance"
},
"cache": {
"ttl": 86400,
"storage": "indexeddb"
}
}
```
### Static Export
For air-gapped environments, export complete dataset:
```http
GET /api/v1/scans/{scanId}/offline-bundle
```
Returns zip containing:
- `vulnerabilities.json` (all pages concatenated)
- `components.json`
- `services.json`
- `provenance.json`
- `manifest.json` (with hashes)
## Links
- Sprint: `docs/implplan/SPRINT_0186_0001_0001_record_deterministic_execution.md` (SC7)
- Roadmap: `docs/modules/scanner/design/standards-convergence-roadmap.md` (SC1)
- Contract: `docs/modules/scanner/design/cdx17-cbom-contract.md` (SC2)