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

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

  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

{
  "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.json
  • services.json
  • provenance.json
  • manifest.json (with hashes)
  • 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)