# 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)