Files
git.stella-ops.org/docs/api/vex-proof-schema.md
2026-01-06 19:07:48 +02:00

11 KiB

VEX Proof Object Schema Reference

Version: 1.0 (stellaops.vex-proof.v1) Last Updated: 2026-01-03

Overview

VEX Proof Objects provide a cryptographically verifiable audit trail of how VEX consensus verdicts are computed. Every VEX resolution in StellaOps produces a proof object that documents the inputs, merge process, and decision rationale.

JSON Schema

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "VEX Proof Object",
  "type": "object",
  "required": ["schema", "proofId", "computedAt", "verdict", "inputs", "mergeTrace", "confidence"],
  "properties": {
    "schema": {
      "type": "string",
      "const": "stellaops.vex-proof.v1"
    },
    "proofId": {
      "type": "string",
      "description": "Unique identifier for this proof"
    },
    "computedAt": {
      "type": "string",
      "format": "date-time",
      "description": "ISO 8601 timestamp of proof computation"
    },
    "digest": {
      "type": "object",
      "description": "Content-addressed hash of the proof"
    },
    "verdict": {
      "$ref": "#/definitions/verdict"
    },
    "inputs": {
      "$ref": "#/definitions/inputs"
    },
    "mergeTrace": {
      "$ref": "#/definitions/mergeTrace"
    },
    "propagation": {
      "$ref": "#/definitions/propagation"
    },
    "conditions": {
      "$ref": "#/definitions/conditions"
    },
    "confidence": {
      "$ref": "#/definitions/confidence"
    }
  }
}

Object Definitions

Verdict

The final consensus result.

Field Type Required Description
vulnerabilityId string Yes CVE or vulnerability identifier
productKey string Yes Product identifier (typically a PURL)
status enum Yes VEX status: affected, not_affected, fixed, under_investigation
justification enum No Justification code if status is not_affected
confidence number Yes Confidence score [0.0, 1.0]
{
  "vulnerabilityId": "CVE-2023-12345",
  "productKey": "pkg:npm/lodash@4.17.21",
  "status": "not_affected",
  "justification": "vulnerable_code_not_in_execute_path",
  "confidence": 0.78
}

Inputs

All VEX statements considered in the consensus.

Field Type Required Description
qualifiedCount integer Yes Number of statements meeting weight threshold
disqualifiedCount integer Yes Number of statements filtered out
statements array Yes Array of input statements
disqualified array No Array of disqualified statements with reasons

Statement Object

Field Type Required Description
id string Yes Statement identifier
source string Yes Source document identifier
issuer object Yes Issuer information
status enum Yes VEX status from this statement
justification enum No Justification if not_affected
weight object Yes Weight calculation details
timestamp datetime Yes Statement timestamp
signatureVerified boolean Yes Whether signature was verified

Issuer Object

Field Type Required Description
id string Yes Issuer identifier
category enum Yes vendor, distributor, community, internal, aggregator
trustTier enum Yes authoritative, trusted, untrusted, unknown

Weight Object

Field Type Required Description
composite number Yes Final composite weight [0.0, 1.0]
factors object Yes Individual weight factors

Weight factors:

  • issuer: Issuer trust weight
  • signature: Signature verification weight
  • freshness: Statement age weight
  • format: Source format weight (OpenVEX vs CSAF vs CycloneDX)
  • specificity: Status specificity weight

MergeTrace

Step-by-step documentation of the merge algorithm.

Field Type Required Description
mode enum Yes Consensus mode used
latticeOrdering array No Status lattice order (for Lattice mode)
steps array Yes Array of merge steps
conflicts array No Array of detected conflicts

Consensus Modes

  • highest_weight: Select statement with highest trust weight
  • weighted_vote: Weighted voting across all statements
  • lattice: Lattice-based conservative consensus
  • authoritative_first: Prefer vendor/authoritative sources

Merge Step

Field Type Required Description
stepNumber integer Yes Sequential step number
statementId string Yes Statement being processed
inputStatus enum Yes Status from this statement
inputWeight number Yes Weight of this statement
action enum Yes initialize, merge, skip
conflictDetected boolean Yes Whether conflict was detected
resolution string No How conflict was resolved
positionAfter enum Yes Current consensus position after step

Conflict

Field Type Required Description
statement1Id string Yes First conflicting statement
statement2Id string Yes Second conflicting statement
status1 enum Yes Status of first statement
status2 enum Yes Status of second statement
severity enum Yes critical, high, medium, low
resolution string Yes Resolution method
winnerId string No Winning statement ID

Propagation

Dependency propagation analysis (optional).

Field Type Required Description
applied boolean Yes Whether propagation was applied
rules array Yes Propagation rules evaluated
paths array No Analyzed dependency paths
inheritedStatus enum No Status inherited via propagation
overrideApplied boolean No Whether propagation overrode consensus

Propagation Rules

  • direct_dependency_affected: Affected status propagates to direct dependents
  • transitive_dependency: Transitive propagation through dependency tree
  • dependency_fixed: Fixed status doesn't propagate transitively
  • dependency_not_affected: NotAffected can propagate under conditions

Conditions

Condition evaluation results (optional).

Field Type Required Description
results array Yes Condition evaluation results
unevaluated array No Conditions that couldn't be evaluated
coverage number Yes Percentage of conditions evaluated

Condition Result

Field Type Required Description
conditionId string Yes Condition identifier
expression string Yes Condition expression
result enum Yes true, false, unknown
contextValue string No Evaluated context value

Condition Types

  • platform: OS/architecture (e.g., linux/amd64)
  • distro: Distribution (e.g., rhel:9)
  • feature: Feature flag condition
  • build_flag: Compile-time flag
  • environment: Environment variable

Confidence

Confidence score breakdown.

Field Type Required Description
score number Yes Overall confidence [0.0, 1.0]
tier enum Yes high, medium, low
components object Yes Score components
improvements array No Suggestions for improving confidence

Score component contributions:

  • weightSpread: Statement weight distribution
  • freshnessBonus: Bonus for recent statements
  • signatureBonus: Bonus for signed statements
  • conflictPenalty: Penalty for conflicts
  • conditionCoverage: Condition evaluation coverage

Digest Computation

The proof digest is computed using RFC 8785 canonical JSON serialization:

  1. Serialize proof object to canonical JSON (sorted keys, minimal escaping)
  2. Compute SHA-256 hash of canonical JSON bytes
  3. Encode as hexadecimal
{
  "digest": {
    "algorithm": "sha256",
    "value": "a1b2c3d4..."
  }
}

Example Proof Object

{
  "schema": "stellaops.vex-proof.v1",
  "proofId": "proof-2026-01-02T10:30:00Z-abc123",
  "computedAt": "2026-01-02T10:30:00Z",
  "digest": {
    "algorithm": "sha256",
    "value": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
  },
  "verdict": {
    "vulnerabilityId": "CVE-2023-12345",
    "productKey": "pkg:npm/lodash@4.17.21",
    "status": "not_affected",
    "justification": "vulnerable_code_not_in_execute_path",
    "confidence": 0.78
  },
  "inputs": {
    "qualifiedCount": 2,
    "disqualifiedCount": 0,
    "statements": [
      {
        "id": "stmt-001",
        "source": "openvex",
        "issuer": {
          "id": "lodash-maintainers",
          "category": "vendor",
          "trustTier": "authoritative"
        },
        "status": "not_affected",
        "justification": "vulnerable_code_not_in_execute_path",
        "weight": {
          "composite": 0.85,
          "factors": {
            "issuer": 0.90,
            "signature": 1.00,
            "freshness": 0.95,
            "format": 1.00,
            "specificity": 0.70
          }
        },
        "timestamp": "2023-06-15T10:30:00Z",
        "signatureVerified": true
      }
    ]
  },
  "mergeTrace": {
    "mode": "lattice",
    "latticeOrdering": ["affected", "under_investigation", "fixed", "not_affected"],
    "steps": [
      {
        "stepNumber": 1,
        "statementId": "stmt-001",
        "inputStatus": "not_affected",
        "inputWeight": 0.85,
        "action": "initialize",
        "conflictDetected": false,
        "positionAfter": "not_affected"
      }
    ],
    "conflicts": []
  },
  "confidence": {
    "score": 0.78,
    "tier": "medium",
    "components": {
      "weightSpread": 0.80,
      "freshnessBonus": 0.05,
      "signatureBonus": 0.05,
      "conflictPenalty": 0.00,
      "conditionCoverage": 0.00
    },
    "improvements": [
      "Add statements from additional authoritative sources",
      "Evaluate platform-specific conditions"
    ]
  }
}

Policy Integration

VEX proofs integrate with the policy gate system via VexProofGate:

Setting Type Default Description
Enabled bool true Enable/disable gate
MinimumConfidenceTier string medium Required confidence tier
RequireProofForNotAffected bool true Require proof for NotAffected
RequireProofForFixed bool false Require proof for Fixed
MaxAllowedConflicts int 5 Maximum allowed conflicts
MaxProofAgeHours int 168 Maximum proof age (hours)
RequireSignedStatements bool false Require all statements signed
MinimumInputStatements int 1 Minimum input statement count