- Added `FilesystemPackRunProvenanceWriter` to write provenance manifests to the filesystem. - Introduced `MongoPackRunArtifactReader` to read artifacts from MongoDB. - Created `MongoPackRunProvenanceWriter` to store provenance manifests in MongoDB. - Developed unit tests for filesystem and MongoDB provenance writers. - Established `ITimelineEventStore` and `ITimelineIngestionService` interfaces for timeline event handling. - Implemented `TimelineIngestionService` to validate and persist timeline events with hashing. - Created PostgreSQL schema and migration scripts for timeline indexing. - Added dependency injection support for timeline indexer services. - Developed tests for timeline ingestion and schema validation.
10 KiB
Vulnerability Explorer architecture
Based on Epic 6 – Vulnerability Explorer; this specification summarises the ledger model, triage workflows, APIs, and export requirements.
1) Ledger data model
-
See
../findings-ledger/schema.mdfor the canonical SQL schema, hashing strategy, and fixtures underpinning these collections. -
Collections / tables
finding_records– canonical, policy-derived findings enriched with advisory, VEX, SBOM, runtime context. IncludespolicyVersion,advisoryRawIds,vexRawIds,sbomComponentId,policyRationale(array of explain bundle URIs or remediation notes returned by/api/policy/eval/batch), andexplainBundleRef.finding_history– append-only state transitions (new,triaged,accepted_risk,remediated,false_positive, etc.) with timestamps, actor, and justification.triage_actions– discrete operator actions (comment, assignment, remediation note, ticket link) with immutable provenance.remediation_plans– structured remediation steps (affected assets, deadlines, recommended fixes, auto-generated from SRM/AI hints).reports– saved report definitions, export manifests, and signatures.
-
Immutability & provenance – All updates are append-only; previous state is recoverable. Records capture
tenant,artifactId,findingKey,policyVersion,sourceRunId,sr mDigest.
2) Triage workflow
- Ingest effective findings from Policy Engine (stream
policy.finding.delta) and on-demand batch evaluations. Projection workers call/api/policy/eval/batchwith ledger event payloads to receive status/severity/label/rationale updates before writingfinding_records. Each delta updatesfinding_records, generates history entries, and triggers notification rules. - Prioritisation uses contextual heuristics: runtime exposure, VEX status, policy severity, AI hints. Stored as
priorityScorewith provenance from Zastava/AI modules. - Assignment & collaboration – Operators claim findings, add comments, attach evidence, and link tickets. Assignment uses Authority identities and RBAC.
- Remediation tracking – Link remediation plans, record progress, and integrate with Scheduler for follow-up scans once fixes deploy.
- Closure – When Policy or rescans mark finding resolved, system logs closure with explain trace and updates audit ledger.
State machine summary:
new -> (triage) triaged -> (remediate) in_progress -> (verify) awaiting_verification -> (scan) remediated
new -> (false_positive) closed_false_positive
new -> (risk_accept) accepted_risk
All transitions require justification; certain transitions (accepted risk) require multi-approver workflow defined by Policy Studio.
3) APIs
GET /v1/findings— filtered listing with pagination, search (artifact, advisory, priority, status, assignee).GET /v1/findings/{id}— detail view (policy context, explain trace, evidence timeline).POST /v1/findings/{id}/actions— create triage action (assign, comment, status change, remediation, ticket link) with DSSE signature support.POST /v1/reports— generate report artifact (JSON, CSV, PDF) defined by saved templates; records manifest + signature.GET /v1/exports/offline— stream deterministic bundle for Offline Kit (findings JSON, history, attachments, manifest).
CLI mirrors these endpoints (stella findings list|view|update|export). Console UI consumes the same APIs via typed clients.
4) AI/automation integration
- Advisory AI contributes remediation hints and conflict explanations stored alongside findings (
aiInsights). - Scheduler integration triggers follow-up scans or policy re-evaluation when remediation plan reaches checkpoint.
- Zastava (Differential SBOM) feeds runtime exposure signals to reprioritise findings automatically.
5) Observability & compliance
- Metrics:
findings_open_total{severity,tenant},findings_mttr_seconds,triage_actions_total{type},report_generation_seconds. - Logs: structured with
findingId,artifactId,advisory,policyVersion,actor,actionType. - Audit exports:
audit_log.jsonlappended whenever state changes; offline bundles include signed audit log and manifest. - Compliance: accepted risk requires dual approval and stores justification plus expiry reminders (raised through Notify).
- Runbook and dashboard stub for demo snapshot:
runbooks/observability.mdandrunbooks/dashboards/vuln-explorer-observability.json(offline import).
6) Identity & access integration
- Scopes –
vuln:view,vuln:investigate,vuln:operate,vuln:auditmap to read-only, triage, workflow, and audit experiences respectively. The deprecatedvuln:readscope is still honoured for legacy tokens but is no longer advertised. - Attribute filters (ABAC) – Authority enforces per-service-account filters via the client-credential parameters
vuln_env,vuln_owner, andvuln_business_tier. Service accounts define the allowed values inauthority.yaml(attributesblock). Tokens include the resolved filters as claims (stellaops:vuln_env,stellaops:vuln_owner,stellaops:vuln_business_tier), and tokens persisted to Mongo retain the same values for audit and revocation. - Audit trail – Every token issuance emits
authority.vuln_attr.*audit properties that mirror the resolved filter set, along withdelegation.service_accountand ordereddelegation.actor[n]entries so Vuln Explorer can correlate access decisions. - Permalinks – Signed permalinks inherit the caller’s ABAC filters; consuming services must enforce the embedded claims in addition to scope checks when resolving permalinks.
- Attachment tokens – Authority mints short-lived tokens (
POST /vuln/attachments/tokens/issue) to gate evidence downloads. Verification (POST /vuln/attachments/tokens/verify) enforces tenant, scope, and ABAC metadata, and emitsvuln.attachment.token.*audit records. - Ledger verification – Offline workflows validate attachments by comparing the Authority-issued token, the Vuln Explorer ledger hash, and the downloaded artefact hash before distribution.
7) Offline bundle requirements
- Bundle structure:
manifest.json(hashes, counts, policy version, generation timestamp).findings.jsonl(current open findings).history.jsonl(state changes).actions.jsonl(comments, assignments, tickets).reports/(generated PDFs/CSVs).signatures/(DSSE envelopes).
- Bundles produced deterministically; Export Center consumes them for mirror profiles.
8) VEX-First Triage UX
Reference: Product advisory
28-Nov-2025 - Vulnerability Triage UX & VEX-First Decisioning.md
8.1 Evidence-First Finding Cards
Each vulnerability finding is displayed as an evidence-first card showing:
- CVE/vulnerability identifier with severity badge
- Package name, version, ecosystem
- Location (file path, container layer, function, call path)
- Scanner and database date
- Status badges:
New,VEX: Not affected,Policy: blocked
Primary actions per card:
- VEX: Set status - Opens VEX decision modal
- Fix PR / View Fix - When available from connected scanners (Snyk/GitLab)
- Attach Evidence - Link PRs, tickets, docs, commits
- Copy audit reference - findingId + attestation digest
8.2 VEX Decision Model
VEX decisions follow the VexDecision schema (docs/schemas/vex-decision.schema.json):
Status values:
NOT_AFFECTED- Vulnerability does not apply to this artifactAFFECTED_MITIGATED- Vulnerable but mitigations in placeAFFECTED_UNMITIGATED- Vulnerable without mitigationsFIXED- Vulnerability has been remediated
Justification types (CSAF/VEX aligned):
CODE_NOT_PRESENTCODE_NOT_REACHABLEVULNERABLE_CODE_NOT_IN_EXECUTE_PATHCONFIGURATION_NOT_AFFECTEDOS_NOT_AFFECTEDRUNTIME_MITIGATION_PRESENTCOMPENSATING_CONTROLSACCEPTED_BUSINESS_RISKOTHER
Scope and validity:
- Decisions can be scoped to specific environments and projects
- Validity windows with
notBeforeandnotAftertimestamps - Expired decisions are surfaced with warnings
8.3 Explainability Panel
Right-side panel with tabs for each finding:
Overview tab:
- Title, severity, package/version
- Scanner + DB date
- Finding history timeline
- Current VEX decision summary
Reachability tab:
- Call path visualization
- Module dependency list
- Runtime usage indicators (when available)
Policy tab:
- Policy evaluation result (PASS/WARN/FAIL)
- Gate details with "this gate failed because..." explanations
- Links to gate definitions
Attestations tab:
- Attestations mentioning this artifact/vulnerability/scan
- Type, subject, predicate, signer, verified status
- "Signed evidence" pill linking to attestation detail
8.4 VEX Decision APIs
New endpoints for VEX decisions:
POST /v1/vex-decisions- Create new VEX decision with optional attestationPATCH /v1/vex-decisions/{id}- Update existing decision (creates superseding record)GET /v1/vex-decisions- List decisions with filtersGET /v1/vex-decisions/{id}- Get decision detail
Request/response follows VexDecisionDto per schema.
8.5 Audit Bundle Export
Immutable audit bundles follow the AuditBundleIndex schema (docs/schemas/audit-bundle-index.schema.json):
Bundle contents:
- Vulnerability reports (scanner outputs)
- SBOM (CycloneDX/SPDX)
- VEX decisions
- Policy evaluations
- Raw attestations (DSSE envelopes)
audit-bundle-index.jsonmanifest with integrity hashes
APIs:
POST /v1/audit-bundles- Create new bundle (async generation)GET /v1/audit-bundles/{bundleId}- Download bundle (ZIP or OCI)GET /v1/audit-bundles- List previously created bundles
8.6 Industry Pattern Alignment
The triage UX aligns with industry patterns from:
| Tool | Pattern Adopted |
|---|---|
| Snyk | PR checks, Fix PRs, ignore with reasons |
| GitLab SCA | Vulnerability Report, status workflow, activity log |
| Harbor/Trivy | Artifact-centric navigation, attestation accessories |
| Anchore | Policy gates with trigger explanations, allowlists |
9) Schemas
The following JSON schemas define the data contracts for VEX and audit functionality:
docs/schemas/vex-decision.schema.json- VEX decision form and persistencedocs/schemas/attestation-vuln-scan.schema.json- Vulnerability scan attestation predicatedocs/schemas/audit-bundle-index.schema.json- Audit bundle manifest
These schemas are referenced by both backend DTOs and frontend TypeScript interfaces.