- 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.
7.1 KiB
7.1 KiB
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)
GET /api/v1/scans/{scanId}/vulnerabilities
Response includes dual CVSS ratings:
{
"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
GET /api/v1/scans/{scanId}/services
Response includes CBOM properties:
{
"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)
GET /api/v1/scans/{scanId}/provenance
Response includes SLSA Source Track:
{
"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
GET /api/v1/evidence/{evidenceHash}
Returns evidence details:
{
"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:
{
"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
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
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
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
- Sort stability: All sorts use secondary key (usually
id) for tie-breaking - Cursor encoding: Deterministic JSON serialization before base64
- Timestamps: UTC ISO-8601, no sub-millisecond precision unless non-zero
- Export ordering: Same ordering rules as API responses
- Filter normalization: Sort filter arrays before query execution
Offline Support
Prefetch Manifest
{
"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:
GET /api/v1/scans/{scanId}/offline-bundle
Returns zip containing:
vulnerabilities.json(all pages concatenated)components.jsonservices.jsonprovenance.jsonmanifest.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)