Files
git.stella-ops.org/docs/VEX_CONSENSUS_GUIDE.md

10 KiB

VEX Consensus and Issuer Trust

This document consolidates the VEX concepts StellaOps relies on: ingesting upstream VEX without rewriting it, correlating evidence across sources, and producing a deterministic, explainable "effective" status for a component-vulnerability pair.

Scope

  • VEX ingestion and provenance (what is stored and why)
  • Correlation (linksets) versus consensus (effective status)
  • Issuer trust and offline operation

This is not an API reference; module dossiers define concrete schemas and endpoints.

Vocabulary (Minimal)

  • VEX statement: a claim about vulnerability status for a product/component (for example: affected, fixed, not_affected, under_investigation).
  • Observation: an immutable record of a single upstream VEX document as received (including provenance and raw payload).
  • Linkset: a deterministic correlation group that ties together statements that refer to the same (vulnerabilityId, productKey) across providers.
  • Consensus decision (effective VEX): the platform's deterministic result after policy rules evaluate available VEX/advisory/reachability evidence.

StellaOps treats upstream VEX as append-only evidence.

An observation records:

  • Provenance: tenant, provider/issuer identity, receive timestamps (UTC), signature status, and content hash.
  • Raw payload: stored losslessly so auditors and operators can retrieve exactly what was ingested.
  • Derived tuples: extracted (vulnerabilityId, productKey, status, justification?, version hints, references) used for correlation and UI presentation.

An observation is never mutated. If upstream publishes a revision, StellaOps stores a new observation and records a supersedes relationship.

Linksets (Correlation Without Consensus)

Linksets exist to make multi-source evidence explainable without collapsing it:

  • Group statements that likely refer to the same product-vulnerability pair.
  • Preserve conflicts (status disagreements, justification divergence, version range clashes) as first-class facts.
  • Provide stable IDs generated from canonical, sorted inputs (deterministic hashing).

Linksets do not invent consensus; they only align evidence so downstream layers (Policy/Console/Exports) can explain what is known and what disagrees.

Consensus (Effective Status)

The effective VEX status is computed by policy evaluation using:

  • Correlated VEX evidence (observations + linksets)
  • Advisory evidence (observations/linksets from Concelier)
  • Optional reachability and other signals

Key properties:

  • Deterministic: the same inputs yield the same output.
  • Explainable: the decision includes an explanation trace and evidence references.
  • Uncertainty-aware: when critical evidence is missing or conflicts are unresolved, the result can remain under_investigation instead of implying safety.

Aggregation-Only Guardrails (AOC)

To avoid hidden rewriting of upstream data, the platform enforces:

  • Raw-first storage: upstream payloads are stored as received; normalized projections are derived but do not replace raw data.
  • No merge of sources: each provider's statements remain independently addressable.
  • Provenance is mandatory: missing provenance or unverifiable signatures are surfaced as ingestion failures or warnings (policy-driven).
  • Idempotent writes: identical content hashes do not create duplicate observations.
  • Deterministic outputs: stable ordering and canonical hashing for linksets and exports.

Issuer Directory and Trust

Issuer trust is a first-class input:

  • Issuers are identified by stable provider IDs and, where applicable, cryptographic identity (certificate chain, key id, transparency proof).
  • The issuer directory defines which issuers are trusted per tenant/environment and how they are weighted/accepted by policy.
  • Offline sites carry required trust material (roots and allowlists) inside the Offline Kit so verification does not require network access.

Console Integration

The Console uses these concepts to keep VEX explainable:

  • VEX views show provider provenance, signature/issuer status, and snapshot timestamps.
  • Conflicts are displayed as conflicts (what disagrees and why), not silently resolved in the UI.
  • The effective VEX status shown in triage views links back to underlying observations/linksets and the policy explanation.

See docs/UI_GUIDE.md for the operator workflow perspective.

Anchor-Aware Mode (v1.1)

Sprint: SPRINT_20260112_004_BE_policy_determinization_attested_rules

Anchor-aware mode enforces cryptographic attestation requirements on VEX proofs used for allow decisions.

VexProofGate Options

Option Type Default Strict Mode
AnchorAwareMode bool false true
RequireVexAnchoring bool false true
RequireRekorVerification bool false true
RequireSignedStatements bool false true
RequireProofForFixed bool false true
MaxAllowedConflicts int 5 0
MaxProofAgeHours int 168 72

Strict Anchor-Aware Preset

For production environments requiring maximum security:

var options = VexProofGateOptions.StrictAnchorAware;
// Enables: RequireVexAnchoring, RequireRekorVerification,
//          RequireSignedStatements, RequireProofForFixed
// Sets: MinimumConfidenceTier=high, MaxAllowedConflicts=0, MaxProofAgeHours=72

Metadata Keys

When passing VEX proof context through policy evaluation:

Key Type Description
vex_proof_anchored bool Whether proof has DSSE anchoring
vex_proof_envelope_digest string DSSE envelope sha256 digest
vex_proof_rekor_verified bool Whether Rekor transparency verified
vex_proof_rekor_log_index long Rekor log index if verified

Failure Reasons

Reason Description
vex_not_anchored VEX proof requires DSSE anchoring but is not anchored
rekor_verification_missing VEX proof requires Rekor verification but not verified

VEX Change Events

Sprint: SPRINT_20260112_006_EXCITITOR_vex_change_events

Excititor emits deterministic events when VEX statements change, enabling policy reanalysis.

Event Types

Event Description Policy Trigger
vex.statement.added New statement ingested Immediate reanalysis
vex.statement.superseded Statement replaced Immediate reanalysis
vex.statement.conflict Status disagreement detected Queue for review
vex.status.changed Effective status changed Immediate reanalysis

Conflict Detection

Conflicts are detected when multiple providers report different statuses for the same vulnerability-product pair:

Conflict Type Description
status_mismatch Different status values (e.g., affected vs not_affected)
trust_tie Equal trust scores with different recommendations
supersession_conflict Disagreement on which statement supersedes

Event Ordering

Events follow deterministic ordering:

  1. Ordered by timestamp (ascending)
  2. Conflict events after related statement events
  3. Same-timestamp events sorted by provider ID

Integration with Policy

Subscribe to VEX events for automatic reanalysis:

subscriptions:
  - event: vex.statement.*
    action: reanalyze
    filter:
      trustScore: { $gte: 0.7 }

See Excititor Architecture for full event schemas.

Offline / Air-Gap Operation

  • VEX observations/linksets are included in Offline Kit snapshots with content hashes and timestamps.
  • Verification workflows (signatures, issuer trust) must work offline using bundled trust roots and manifests.
  • The Console should surface snapshot identity and staleness budgets when operating offline.
  • docs/modules/excititor/architecture.md
  • docs/modules/vex-lens/architecture.md
  • docs/ARCHITECTURE_OVERVIEW.md
  • docs/OFFLINE_KIT.md
  • docs/modules/policy/determinization-api.md

Grey Queue and Unknown Mapping

Sprint: SPRINT_20260112_004_POLICY_unknowns_determinization_greyqueue

When VEX correlation produces inconclusive results, observations are routed to the Grey Queue for monitoring or manual adjudication.

Mapping to OpenVEX Status

Uncertain observations preserve OpenVEX spec alignment:

Internal State OpenVEX Status Description
PendingDeterminization under_investigation Evidence incomplete; monitoring active
Disputed under_investigation Conflicting evidence from multiple sources
GuardedPass under_investigation Allowed with runtime guardrails

VEX Conflict Types

The Grey Queue surfaces VEX-specific conflicts:

Conflict Example Resolution Path
Status mismatch Vendor says not_affected, distro says affected Trust-weighted consensus or manual
Justification gap Status not_affected but no justification provided Request clarification or manual
Version range conflict Overlapping but different affected ranges Manual analysis
Supersession dispute Multiple statements claim to supersede Timestamp and trust resolution

Deterministic Conflict Detection

Conflicts are detected via structured comparison:

  1. Same vulnerability, same product, different statusVexStatusConflict
  2. VEX not_affected + confirmed reachabilityVexReachabilityContradiction
  3. Multiple issuers, equal trust, opposite conclusionsTrustTie

Console Behavior for Grey Queue

When displaying Grey Queue items:

  • Show the observation state badge (e.g., "Pending" or "Disputed")
  • Display all conflicting sources with provider identity
  • Surface the reanalysis fingerprint for reproducibility
  • List pending triggers awaiting data
  • Provide action buttons for manual resolution

Offline Grey Queue

In offline/air-gap mode:

  • Grey Queue state is included in Offline Kit snapshots
  • Manual adjudications are recorded locally and synced on reconnection
  • Staleness budgets apply to pending determinations
  • Conflict detection works with cached issuer trust data