# Confidence Scoring System ## Overview The StellaOps confidence scoring system quantifies the reliability of vulnerability assessments by weighing multiple evidence sources. This enables policy decisions that account for uncertainty and evidence quality. --- ## Scoring Formula ``` ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ CONFIDENCE SCORING FORMULA │ ├─────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────────────────────────────────────────────────────────────────────────┐ │ │ │ │ │ │ │ │ │ │ │ FinalScore = Σ (Weight_i × NormalizedScore_i) × 100 │ │ │ │ i │ │ │ │ │ │ │ │ Where: │ │ │ │ i ∈ {Reachability, Runtime, VEX, Provenance, Policy} │ │ │ │ Σ Weight_i = 1.0 │ │ │ │ NormalizedScore_i ∈ [0.0, 1.0] │ │ │ │ FinalScore ∈ [0, 100] │ │ │ │ │ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌──────────────────────────────────────────────────────────────────────────────┐ │ │ │ DEFAULT WEIGHT CONFIGURATION │ │ │ │ │ │ │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ │ │ │ │ │ │ │ │ ████████████████████████████████ Reachability (RCH): 0.30 │ │ │ │ │ │ ██████████████████████████ Runtime (RTS): 0.25 │ │ │ │ │ │ ████████████████████ VEX: 0.20 │ │ │ │ │ │ ██████████████ Provenance (PRV): 0.15 │ │ │ │ │ │ ██████████ Policy (POL): 0.10 │ │ │ │ │ │ ──────────────────────────────────────────────────────────── │ │ │ │ │ │ = 1.00 │ │ │ │ │ │ │ │ │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────────────┘ ``` --- ## Factor Details ### 1. Reachability Factor (RCH) - Weight: 0.30 ``` ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ REACHABILITY FACTOR (RCH) │ ├─────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ Purpose: Measure confidence that vulnerable code is reachable from entry points │ │ Source: ReachGraph call graph analysis + 8-state reachability lattice │ │ Weight: 0.30 (highest - most impactful for exploitability) │ │ │ │ ┌──────────────────────────────────────────────────────────────────────────────┐ │ │ │ SCORE MAPPING │ │ │ │ │ │ │ │ Reachability State │ Score │ Rationale │ │ │ │ ────────────────────────────┼───────┼──────────────────────────────────────│ │ │ │ LiveExploitPath │ 1.00 │ Confirmed exploitable path exists │ │ │ │ │ │ with runtime proof │ │ │ │ ────────────────────────────┼───────┼──────────────────────────────────────│ │ │ │ DynamicReachable │ 0.90 │ Observed at runtime via eBPF │ │ │ │ │ │ Strong evidence of usage │ │ │ │ ────────────────────────────┼───────┼──────────────────────────────────────│ │ │ │ StaticReachable │ 0.70 │ Static analysis found call path │ │ │ │ │ │ May not execute in practice │ │ │ │ ────────────────────────────┼───────┼──────────────────────────────────────│ │ │ │ PotentiallyReachable │ 0.50 │ Import exists but no direct call │ │ │ │ │ │ Could be reached via reflection/eval │ │ │ │ ────────────────────────────┼───────┼──────────────────────────────────────│ │ │ │ Unknown │ 0.30 │ Insufficient data to determine │ │ │ │ │ │ Conservative middle ground │ │ │ │ ────────────────────────────┼───────┼──────────────────────────────────────│ │ │ │ GateBlocked │ 0.15 │ Dead code behind feature flag │ │ │ │ │ │ Low but not zero risk │ │ │ │ ────────────────────────────┼───────┼──────────────────────────────────────│ │ │ │ NotReachable │ 0.10 │ Static analysis proves no path │ │ │ │ │ │ Still small residual risk │ │ │ │ ────────────────────────────┼───────┼──────────────────────────────────────│ │ │ │ NotApplicable │ 0.00 │ Platform/language mismatch │ │ │ │ │ │ Cannot affect this system │ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌──────────────────────────────────────────────────────────────────────────────┐ │ │ │ EXAMPLE │ │ │ │ │ │ │ │ Finding: CVE-2021-23337 in lodash@4.17.20 │ │ │ │ Reachability State: StaticReachable │ │ │ │ RCH Score: 0.70 │ │ │ │ │ │ │ │ Contribution to final: 0.70 × 0.30 = 0.210 (21 points) │ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────────────┘ ``` ### 2. Runtime Factor (RTS) - Weight: 0.25 ``` ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ RUNTIME FACTOR (RTS) │ ├─────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ Purpose: Incorporate runtime observation evidence from eBPF/Signals │ │ Source: Hot Symbol Index (signals.hot_symbols table) │ │ Weight: 0.25 │ │ │ │ ┌──────────────────────────────────────────────────────────────────────────────┐ │ │ │ SCORE MAPPING │ │ │ │ │ │ │ │ Runtime Observation │ Score │ Rationale │ │ │ │ ────────────────────────────────┼───────┼──────────────────────────────────│ │ │ │ High frequency observation │ 1.00 │ Function called frequently │ │ │ │ (invocation_count > 1000/day) │ │ Definitely in use │ │ │ │ ────────────────────────────────┼───────┼──────────────────────────────────│ │ │ │ Moderate observation │ 0.80 │ Function called at least once │ │ │ │ (invocation_count > 0) │ │ Confirmed in active code path │ │ │ │ ────────────────────────────────┼───────┼──────────────────────────────────│ │ │ │ No observation (short window) │ 0.50 │ Not seen yet, but observation │ │ │ │ (< 7 days of monitoring) │ │ window is short │ │ │ │ ────────────────────────────────┼───────┼──────────────────────────────────│ │ │ │ No observation (long window) │ 0.20 │ 30+ days of monitoring with │ │ │ │ (> 30 days, no calls) │ │ no observation - likely unused │ │ │ │ ────────────────────────────────┼───────┼──────────────────────────────────│ │ │ │ No runtime posture │ 0.50 │ eBPF agent not deployed │ │ │ │ (observation not available) │ │ Cannot contribute evidence │ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌──────────────────────────────────────────────────────────────────────────────┐ │ │ │ OBSERVATION WINDOW DECAY │ │ │ │ │ │ │ │ Score decreases over time if function is not observed: │ │ │ │ │ │ │ │ Days without observation │ Score │ │ │ │ ─────────────────────────┼────── │ │ │ │ 0-7 │ 0.50 (neutral - too early to tell) │ │ │ │ 8-14 │ 0.40 │ │ │ │ 15-21 │ 0.35 │ │ │ │ 22-30 │ 0.30 │ │ │ │ 31+ │ 0.20 (strong evidence of non-use) │ │ │ │ │ │ │ │ Formula: score = 0.50 - (days / 100) clamped to [0.20, 0.50] │ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌──────────────────────────────────────────────────────────────────────────────┐ │ │ │ EXAMPLE │ │ │ │ │ │ │ │ Finding: CVE-2021-23337 in lodash@4.17.20 │ │ │ │ Runtime: Not observed (14 days of monitoring) │ │ │ │ RTS Score: 0.40 │ │ │ │ │ │ │ │ Contribution to final: 0.40 × 0.25 = 0.100 (10 points) │ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────────────┘ ``` ### 3. VEX Factor - Weight: 0.20 ``` ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ VEX FACTOR │ ├─────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ Purpose: Incorporate vendor VEX statements about exploitability │ │ Source: VexLens consensus engine (aggregates multiple VEX issuers) │ │ Weight: 0.20 │ │ │ │ ┌──────────────────────────────────────────────────────────────────────────────┐ │ │ │ VEX STATUS SCORING │ │ │ │ │ │ │ │ VEX Status │ Base │ Trust │ Final │ Rationale │ │ │ │ │ Score │ Mult. │ Score │ │ │ │ │ ───────────────────────┼───────┼────────┼───────┼──────────────────────────│ │ │ │ affected (exploitable) │ 1.00 │ ×trust │ varies│ Vendor confirms vuln │ │ │ │ │ │ │ │ applies to this product │ │ │ │ ───────────────────────┼───────┼────────┼───────┼──────────────────────────│ │ │ │ under_investigation │ 0.70 │ ×1.0 │ 0.70 │ Vendor is analyzing │ │ │ │ │ │ │ │ inconclusive │ │ │ │ ───────────────────────┼───────┼────────┼───────┼──────────────────────────│ │ │ │ no VEX available │ 0.50 │ ×1.0 │ 0.50 │ No statement - neutral │ │ │ │ │ │ │ │ │ │ │ │ ───────────────────────┼───────┼────────┼───────┼──────────────────────────│ │ │ │ not_affected │ 0.20 │ ×trust │ varies│ Vendor says not vuln │ │ │ │ │ │ │ │ (mitigated, not present) │ │ │ │ ───────────────────────┼───────┼────────┼───────┼──────────────────────────│ │ │ │ fixed │ 0.10 │ ×trust │ varies│ Vendor confirms fixed │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌──────────────────────────────────────────────────────────────────────────────┐ │ │ │ ISSUER TRUST LEVELS │ │ │ │ │ │ │ │ Trust is based on issuer reputation and verification: │ │ │ │ │ │ │ │ ┌────────────────────────────────────────────────────────────────────┐ │ │ │ │ │ Trust Level │ Multiplier │ Issuers │ │ │ │ │ │ ────────────┼────────────┼────────────────────────────────────────│ │ │ │ │ │ Very High │ 1.0 │ Verified vendor (e.g., RedHat, Ubuntu)│ │ │ │ │ │ High │ 0.9 │ Trusted third-party (e.g., Snyk, NIST)│ │ │ │ │ │ Medium │ 0.7 │ Community maintainer │ │ │ │ │ │ Low │ 0.5 │ Unknown/unverified source │ │ │ │ │ │ Contested │ 0.3 │ Multiple conflicting VEX statements │ │ │ │ │ └────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌──────────────────────────────────────────────────────────────────────────────┐ │ │ │ CONSENSUS CALCULATION │ │ │ │ │ │ │ │ When multiple VEX statements exist: │ │ │ │ │ │ │ │ consensus_score = Σ(vex_score_i × trust_i) / Σ(trust_i) │ │ │ │ │ │ │ │ Example: │ │ │ │ ┌────────────────────────────────────────────────────────────────────┐ │ │ │ │ │ Issuer │ Status │ Base │ Trust │ Weighted │ │ │ │ │ │ ─────────────┼───────────────┼──────┼───────┼────────────────────│ │ │ │ │ │ RedHat │ not_affected │ 0.20 │ 1.0 │ 0.20 × 1.0 = 0.20 │ │ │ │ │ │ Ubuntu │ not_affected │ 0.20 │ 1.0 │ 0.20 × 1.0 = 0.20 │ │ │ │ │ │ Community │ affected │ 1.00 │ 0.7 │ 1.00 × 0.7 = 0.70 │ │ │ │ │ │ ─────────────┼───────────────┼──────┼───────┼────────────────────│ │ │ │ │ │ Weighted sum │ │ │ 2.7 │ 1.10 │ │ │ │ │ └────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ Consensus = 1.10 / 2.7 = 0.407 (weighted toward vendor statements) │ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────────────┘ ``` ### 4. Provenance Factor (PRV) - Weight: 0.15 ``` ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ PROVENANCE FACTOR (PRV) │ ├─────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ Purpose: Account for supply chain trust and build provenance │ │ Source: SLSA attestations, DSSE signatures, Rekor transparency log │ │ Weight: 0.15 │ │ │ │ ┌──────────────────────────────────────────────────────────────────────────────┐ │ │ │ SCORE MAPPING │ │ │ │ │ │ │ │ Provenance Level │ Score │ Rationale │ │ │ │ ────────────────────────────────┼───────┼───────────────────────────────────│ │ │ │ Unknown source │ 1.00 │ No attestation - highest risk │ │ │ │ (no attestation) │ │ Cannot verify integrity │ │ │ │ ────────────────────────────────┼───────┼───────────────────────────────────│ │ │ │ Signed but unverified │ 0.80 │ Signature present but no │ │ │ │ (signature, no SLSA) │ │ SLSA attestation │ │ │ │ ────────────────────────────────┼───────┼───────────────────────────────────│ │ │ │ SLSA L1 │ 0.60 │ Documented build process │ │ │ │ (documented build) │ │ │ │ │ │ ────────────────────────────────┼───────┼───────────────────────────────────│ │ │ │ SLSA L2 │ 0.40 │ Signed provenance from │ │ │ │ (signed provenance) │ │ hosted build service │ │ │ │ ────────────────────────────────┼───────┼───────────────────────────────────│ │ │ │ SLSA L3 │ 0.30 │ Hardened builds + signed │ │ │ │ (hardened builds) │ │ provenance │ │ │ │ ────────────────────────────────┼───────┼───────────────────────────────────│ │ │ │ SLSA L4 / Reproducible │ 0.10 │ Fully reproducible build │ │ │ │ (reproducible build) │ │ verified by multiple parties │ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌──────────────────────────────────────────────────────────────────────────────┐ │ │ │ INTERPRETATION │ │ │ │ │ │ │ │ Note: Lower provenance score = LOWER confidence in exploitability │ │ │ │ │ │ │ │ This seems counterintuitive, but the logic is: │ │ │ │ - Unknown provenance means we can't trust the package at all │ │ │ │ - Untrusted packages should be treated as MORE suspicious │ │ │ │ - Better provenance = more confidence the package is what it claims │ │ │ │ │ │ │ │ So: High provenance score → higher confidence the finding is accurate │ │ │ │ Low provenance score → less trust in the package itself │ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────────────┘ ``` ### 5. Policy Factor (POL) - Weight: 0.10 ``` ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ POLICY FACTOR (POL) │ ├─────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ Purpose: Incorporate organizational policy exceptions and overrides │ │ Source: Exception store (approved waivers, risk acceptances) │ │ Weight: 0.10 (lowest - modifies but doesn't override evidence) │ │ │ │ ┌──────────────────────────────────────────────────────────────────────────────┐ │ │ │ SCORE MAPPING │ │ │ │ │ │ │ │ Exception Status │ Score │ Rationale │ │ │ │ ────────────────────────────────┼───────┼───────────────────────────────────│ │ │ │ No exception │ 1.00 │ Standard policy applies │ │ │ │ │ │ Full risk consideration │ │ │ │ ────────────────────────────────┼───────┼───────────────────────────────────│ │ │ │ Time-bounded exception │ 0.50 │ Approved temporary waiver │ │ │ │ (expires in < 30 days) │ │ Reduced urgency │ │ │ │ ────────────────────────────────┼───────┼───────────────────────────────────│ │ │ │ Long-term exception │ 0.30 │ Approved extended waiver │ │ │ │ (expires in 30-90 days) │ │ Risk accepted by org │ │ │ │ ────────────────────────────────┼───────┼───────────────────────────────────│ │ │ │ Permanent waiver │ 0.10 │ Accepted risk - will not fix │ │ │ │ (no expiration) │ │ (e.g., false positive, legacy) │ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌──────────────────────────────────────────────────────────────────────────────┐ │ │ │ EXCEPTION METADATA │ │ │ │ │ │ │ │ Exceptions are tracked with: │ │ │ │ • Approver (who authorized) │ │ │ │ • Justification (why accepted) │ │ │ │ • Expiration (when to re-evaluate) │ │ │ │ • Scope (specific CVE, package, or image) │ │ │ │ • Compensating controls (mitigations in place) │ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────────────┘ ``` --- ## Complete Calculation Example ``` ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ COMPLETE CALCULATION EXAMPLE │ ├─────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ Finding: CVE-2021-23337 (lodash template injection) │ │ Package: pkg:npm/lodash@4.17.20 │ │ Image: docker.io/myorg/app:v1.2.3 │ │ │ │ ┌──────────────────────────────────────────────────────────────────────────────┐ │ │ │ EVIDENCE COLLECTION │ │ │ │ │ │ │ │ 1. REACHABILITY │ │ │ │ State: StaticReachable │ │ │ │ Evidence: BFS found path [main.handler → render.compile → lodash.template] │ │ │ Score: 0.70 │ │ │ │ │ │ │ │ 2. RUNTIME │ │ │ │ Observation: Not observed │ │ │ │ Monitoring window: 14 days │ │ │ │ Score: 0.40 │ │ │ │ │ │ │ │ 3. VEX │ │ │ │ Statements: None available │ │ │ │ Score: 0.50 (neutral) │ │ │ │ │ │ │ │ 4. PROVENANCE │ │ │ │ Level: SLSA L2 (signed provenance) │ │ │ │ Score: 0.40 │ │ │ │ │ │ │ │ 5. POLICY │ │ │ │ Exception: None │ │ │ │ Score: 1.00 │ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌──────────────────────────────────────────────────────────────────────────────┐ │ │ │ WEIGHTED CALCULATION │ │ │ │ │ │ │ │ ┌───────────────┬────────┬────────┬──────────────────────────────────┐ │ │ │ │ │ Factor │ Score │ Weight │ Weighted Score │ │ │ │ │ ├───────────────┼────────┼────────┼──────────────────────────────────┤ │ │ │ │ │ Reachability │ 0.70 │ 0.30 │ 0.70 × 0.30 = 0.210 │ │ │ │ │ │ Runtime │ 0.40 │ 0.25 │ 0.40 × 0.25 = 0.100 │ │ │ │ │ │ VEX │ 0.50 │ 0.20 │ 0.50 × 0.20 = 0.100 │ │ │ │ │ │ Provenance │ 0.40 │ 0.15 │ 0.40 × 0.15 = 0.060 │ │ │ │ │ │ Policy │ 1.00 │ 0.10 │ 1.00 × 0.10 = 0.100 │ │ │ │ │ ├───────────────┼────────┼────────┼──────────────────────────────────┤ │ │ │ │ │ TOTAL │ │ 1.00 │ 0.570 │ │ │ │ │ └───────────────┴────────┴────────┴──────────────────────────────────┘ │ │ │ │ │ │ │ │ Final Confidence Score = 0.570 × 100 = 57 │ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌──────────────────────────────────────────────────────────────────────────────┐ │ │ │ VISUALIZATION │ │ │ │ │ │ │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ │ │ │ │ │ │ │ │ ███████████████████████████████████████████████░░░░░░░░░░░░░░░░░ │ │ │ │ │ │ |---------------- 57% confidence ------------------| │ │ │ │ │ │ │ │ │ │ │ │ Component breakdown: │ │ │ │ │ │ │ │ │ │ │ │ RCH ████████████████████▓ 21% (StaticReachable) │ │ │ │ │ │ RTS ██████████░░░░░░░░░░ 10% (Not observed) │ │ │ │ │ │ VEX ██████████░░░░░░░░░░ 10% (No VEX) │ │ │ │ │ │ PRV ██████░░░░░░░░░░░░░░ 6% (SLSA L2) │ │ │ │ │ │ POL ██████████░░░░░░░░░░ 10% (No exception) │ │ │ │ │ │ ──────────────────────────────────────────────── │ │ │ │ │ │ │ │ │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ Interpretation: │ │ │ │ • Medium-high confidence this vulnerability is exploitable │ │ │ │ • Static reachability is main contributor │ │ │ │ • Would benefit from runtime observation to confirm/deny │ │ │ │ • No VEX statements to modify assessment │ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────────────┘ ``` --- ## Configuration ```yaml # Policy engine confidence configuration confidence: weights: reachability: 0.30 runtime: 0.25 vex: 0.20 provenance: 0.15 policy: 0.10 # Reachability state mappings reachability_scores: LiveExploitPath: 1.00 DynamicReachable: 0.90 StaticReachable: 0.70 PotentiallyReachable: 0.50 Unknown: 0.30 GateBlocked: 0.15 NotReachable: 0.10 NotApplicable: 0.00 # Runtime observation decay runtime: base_observed_score: 0.80 high_frequency_threshold: 1000 # calls/day decay_rate: 0.01 # per day without observation min_score: 0.20 neutral_score: 0.50 # when no runtime data # VEX status mappings vex_scores: affected: 1.00 under_investigation: 0.70 not_affected: 0.20 fixed: 0.10 no_vex: 0.50 # Trust levels for VEX issuers issuer_trust: verified_vendor: 1.0 trusted_third_party: 0.9 community: 0.7 unknown: 0.5 contested: 0.3 # SLSA provenance levels provenance_scores: unknown: 1.00 signed_only: 0.80 slsa_l1: 0.60 slsa_l2: 0.40 slsa_l3: 0.30 slsa_l4: 0.10 # Policy exception mappings exception_scores: none: 1.00 temporary_30d: 0.50 temporary_90d: 0.30 permanent: 0.10 ``` --- ## Related Documentation - [Policy Engine Data Pipeline](policy-engine-data-pipeline.md) - Complete data flow - [K4 Lattice Logic](k4-lattice-logic.md) - Four-valued logic for policy decisions - [Policy Evaluation Flow](../../flows/04-policy-evaluation-flow.md) - End-to-end flow - [Reachability Drift Alert Flow](../../flows/19-reachability-drift-alert-flow.md) - Runtime updates