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

4.5 KiB
Raw Blame History

Status

This document tracks the future-looking risk scoring model for Excititor. The calculation below is not active yet; Sprint 7 work will add the required schema fields, policy controls, and services. Until that ships, Excititor emits consensus statuses without numeric scores.

Scoring model (target state)

S = Gate(VEX_status) × W_trust(source) × [Severity_base × (1 + α·KEV + β·EPSS)]

  • Gate(VEX_status): affected/under_investigation → 1, not_affected/fixed → 0. A trusted “not affected” or “fixed” still zeroes the score.
  • W_trust(source): normalized policy weight (baseline 01). Policies may opt into >1 boosts for signed vendor feeds once Phase 1 closes.
  • Severity_base: canonical numeric severity from Concelier (CVSS or org-defined scale).
  • KEV flag: 0/1 boost when CISA Known Exploited Vulnerabilities applies.
  • EPSS: probability [0,1]; bounded multiplier.
  • α, β: configurable coefficients (default α=0.25, β=0.5) stored in policy.

Safeguards: freeze boosts when product identity is unknown, clamp outputs ≥0, and log every factor in the audit trail.

Implementation roadmap

Phase Scope Artifacts
Phase 1 Schema foundations Extend Excititor consensus/claims and Concelier canonical advisories with severity, KEV, EPSS, and expose α/β + weight ceilings in policy. Sprint 7 tasks EXCITITOR-CORE-02-001, EXCITITOR-POLICY-02-001, EXCITITOR-STORAGE-02-001, FEEDCORE-ENGINE-07-001.
Phase 2 Deterministic score engine Implement a scoring component that executes alongside consensus and persists score envelopes with hashes. Planned task EXCITITOR-CORE-02-002 (backlog).
Phase 3 Surfacing & enforcement Expose scores via WebService/CLI, integrate with Concelier noise priors, and enforce policy-based suppressions. To be scheduled after Phase 2.

Policy controls (Phase 1)

Operators tune scoring inputs through the Excititor policy document:

excititor:
  policy:
    weights:
      vendor: 1.10      # per-tier weight
      ceiling: 1.40     # max clamp applied to tiers and overrides (1.05.0)
    providerOverrides:
      trusted.vendor: 1.35
    scoring:
      alpha: 0.30       # KEV boost coefficient (defaults to 0.25)
      beta: 0.60        # EPSS boost coefficient (defaults to 0.50)
  • All weights (tiers + overrides) are clamped to [0, weights.ceiling] with structured warnings when a value is out of range or not a finite number.
  • weights.ceiling itself is constrained to [1.0, 5.0], preserving prior behaviour when omitted.
  • scoring.alpha / scoring.beta accept non-negative values up to 5.0; values outside the range fall back to defaults and surface diagnostics to operators.

Data model (after Phase 1)

{
  "vulnerabilityId": "CVE-2025-12345",
  "product": "pkg:name@version",
  "consensus": {
    "status": "affected",
    "policyRevisionId": "rev-12",
    "policyDigest": "0D9AEC…"
  },
  "signals": {
    "severity": {"scheme": "CVSS:3.1", "score": 7.5},
    "kev": true,
    "epss": 0.40
  },
  "policy": {
    "weight": 1.15,
    "alpha": 0.25,
    "beta": 0.5
  },
  "score": {
    "value": 10.8,
    "generatedAt": "2025-11-05T14:12:30Z",
    "audit": [
      "gate:affected",
      "weight:1.15",
      "severity:7.5",
      "kev:1",
      "epss:0.40"
    ]
  }
}

Operational guidance

  • Inputs: Concelier delivers severity/KEV/EPSS via the advisory event log; Excititor connectors load VEX statements. Policy owns trust tiers and coefficients.
  • Processing: the scoring engine (Phase 2) runs next to consensus, storing results with deterministic hashes so exports and attestations can reference them.
  • Consumption: WebService/CLI will return consensus plus score; scanners may suppress findings only when policy-authorized VEX gating and signed score envelopes agree.

Pseudocode (Phase 2 preview)

def risk_score(gate, weight, severity, kev, epss, alpha, beta, freeze_boosts=False):
    if gate == 0:
        return 0
    if freeze_boosts:
        kev, epss = 0, 0
    boost = 1 + alpha * kev + beta * epss
    return max(0, weight * severity * boost)

FAQ

  • Can operators opt out? Set α=β=0 or keep weights ≤1.0 via policy.
  • What about missing signals? Treat them as zero and log the omission.
  • When will this ship? Phase 1 is planned for Sprint 7; later phases depend on connector coverage and attestation delivery.