Files
git.stella-ops.org/docs/product-advisories/01-Dec-2025 - Proof-Linked VEX UI Developer Guidelines.md
StellaOps Bot 44171930ff
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
feat: Add UI benchmark driver and scenarios for graph interactions
- Introduced `ui_bench_driver.mjs` to read scenarios and fixture manifest, generating a deterministic run plan.
- Created `ui_bench_plan.md` outlining the purpose, scope, and next steps for the benchmark.
- Added `ui_bench_scenarios.json` containing various scenarios for graph UI interactions.
- Implemented tests for CLI commands, ensuring bundle verification and telemetry defaults.
- Developed schemas for orchestrator components, including replay manifests and event envelopes.
- Added mock API for risk management, including listing and statistics functionalities.
- Implemented models for risk profiles and query options to support the new API.
2025-12-02 01:28:17 +02:00

5.1 KiB

Proof-Linked VEX UI Developer Guidelines

Compiled: 2025-12-01 (UTC)

Purpose

Any VEX-influenced verdict a user sees (Findings, Advisories & VEX, Vuln Explorer, etc.) must be directly traceable to concrete evidence: normalized VEX claims, their DSSE/signatures, and the policy explain trace. Every "Not Affected" badge is a verifiable link to the proof.

What this solves (in one line)

Every "Not Affected" badge becomes a verifiable link to why it is safe.

UX pattern (at a glance)

  • Badge: Not Affected (green pill) always renders as a link.
  • On click: open a right-side drawer with three tabs:
    1. Evidence (DSSE / in-toto / Sigstore)
    2. Attestation (predicate details + signer)
    3. Reasoning Graph (the node + edges that justify the verdict)
  • Hover state: mini popover showing proof types available (e.g., "DSSE, SLSA attestation, Graph node").

Data model (API & DB)

Canonical object returned by VEX API for each finding:

{
  "findingId": "vuln:CVE-2024-12345@pkg:docker/alpine@3.19",
  "status": "not_affected",
  "justificationCode": "vex:not_present",
  "proof": {
    "dsse": {
      "envelopeDigest": "sha256-…",
      "rekorEntryId": "e3f1…",
      "downloadUrl": "https://…/dsse/e3f1…",
      "signer": { "name": "StellaOps Authority", "keyId": "SHA256:…" }
    },
    "attestation": {
      "predicateType": "slsa/v1",
      "attestationId": "att:01H…",
      "downloadUrl": "https://…/att/01H…"
    },
    "graph": {
      "nodeId": "gx:NA-78f…",
      "revision": "gx-r:2025-11-30T12:01:22Z",
      "explainUrl": "https://…/graph?rev=gx-r:…&node=NA-78f…"
    }
  },
  "receipt": {
    "algorithm": "CVSS:4.0",
    "inputsHash": "sha256-…",
    "computedAt": "2025-11-30T12:01:22Z"
  }
}

Suggested Postgres tables:

  • vex_findings(finding_id, status, justification_code, graph_node_id, graph_rev, dsse_digest, rekor_id, attestation_id, created_at, updated_at)
  • proof_artifacts(id, type, digest, url, signer_keyid, meta jsonb)
  • graph_revisions(revision_id, created_at, root_hash)

API contract (minimal)

  • GET /vex/findings/:id -> returns the object above.
  • GET /proofs/:type/:id -> streams artifact (with Content-Disposition: attachment).
  • GET /graph/explain?rev=…&node=… -> returns a JSON justification subgraph.
  • Security headers: Content-SHA256, Digest, X-Proof-Root (graph root hash), and X-Signer-KeyId.

Angular UI spec (drop-in)

Component: FindingStatusBadge

<button class="badge badge--ok" (click)="drawer.open(finding.proof)">
  Not Affected
</button>

Drawer layout (3 tabs):

  1. Evidence
    • DSSE digest (copy button)
    • Rekor entry (open in new tab)
    • "Download envelope"
  2. Attestation
    • Predicate type
    • Attestation ID
    • "Download attestation"
  3. Reasoning Graph
    • Node ID + Revision
    • Inline explainer ("Why safe?" bullets)
    • "Open full graph" (routes to /graph?rev=…&node=…)

Micro-interactions:

  • Copy-to-clipboard with toast ("Digest copied").
  • If any artifact missing, show a yellow "Partial Proof" ribbon listing what is absent.

Visual language:

  • Badges: Not Affected = solid green; Partial Proof = olive with warning dot; No Proof = gray outline (still clickable, explains absence).
  • Proof chips: small caps labels DSSE, ATTESTATION, GRAPH; each chip opens its subsection.

Validation (trust & integrity):

  • On drawer open, the UI calls HEAD /proofs/... to fetch Digest header and X-Proof-Root; compare to stored digests. If mismatch, show red "Integrity Mismatch" banner with retry and report.

Telemetry (debugging):

  • Emit events: proof_drawer_opened, proof_artifact_downloaded, graph_explain_viewed (include findingId, artifactType, latencyMs, integrityStatus).

Developer checklist:

  • Every not_affected status must include at least one proof artifact.
  • Badge is never a dead label; always clickable.
  • Drawer validates artifact digests before rendering contents.
  • "Open full graph" deep-links with rev + node (stable and shareable).
  • Graceful partials: show what is present and what is missing.
  • Accessibility: focus trap in drawer, aria-labels for chips, keyboard nav.

Test cases (quick):

  1. Happy path: all three proofs present; digests match; downloads work.
  2. Partial proof: DSSE present, attestation missing; drawer shows warning ribbon.
  3. Integrity fail: server returns different digest; red banner appears; badge stays clickable.
  4. Graph only: reasoning node present; DSSE/attestation absent; explains rationale clearly.

Optional nice-to-haves:

  • Permalinks: copyable URL that re-opens the drawer to the same tab.
  • QR export: downloadable "proof card" PNG with digests + signer (for audit packets).
  • Offline kit: bundle DSSE, attestation, and a compact graph slice in a .tar.zst for air-gapped review.

If needed, this can be turned into:

  • A small Angular module (ProofDrawerModule) + styles.
  • A .NET 10 controller stub with integrity headers.
  • Fixture JSON so teams can wire it up quickly.
  • docs/ui/console-overview.md
  • docs/ui/advisories-and-vex.md
  • docs/ui/findings.md
  • src/VexLens/StellaOps.VexLens/AGENTS.md and TASKS.md
  • docs/policy/overview.md