Files
git.stella-ops.org/docs/reachability/lattice.md
Vladimir Moushkov 1995883476
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Add Decision Capsules, hybrid reachability, and evidence-linked VEX docs
Introduces new marketing bridge documents for Decision Capsules, Hybrid Reachability, and Evidence-Linked VEX. Updates product vision, README, key features, moat, reachability, and VEX consensus docs to reflect four differentiating capabilities: signed reachability (hybrid static/runtime), deterministic replay, explainable policy with evidence-linked VEX, and sovereign/offline operation. All scan decisions are now described as sealed, reproducible, and audit-grade, with explicit handling of 'Unknown' states and hybrid reachability evidence.
2025-12-11 14:15:07 +02:00

9.1 KiB
Raw Blame History

Reachability Lattice & Scoring Model

Status: Draft mirrors the December 2025 advisory on confidence-based reachability. Owners: Scanner Guild · Policy Guild · Signals Guild.

Stella Ops isn't just another scanner—it's a different product category: deterministic, evidence-linked vulnerability decisions that survive auditors, regulators, and supply-chain propagation.

This document defines the confidence lattice, evidence types, mitigation scoring, and policy gates used to turn static/runtime signals into reproducible reachability decisions and VEX statuses.


1. Overview

Key differentiator: Unlike simplistic yes/no reachability approaches, the Stella Ops lattice model explicitly handles an "Unknown" (under_investigation) state, ensuring incomplete data doesn't lead to false safety. Every VEX decision is evidence-linked with proof pointers to the underlying reachability evidence.

Classic "reachable: true/false" answers are too brittle. Stella Ops models reachability as an ordered lattice with explicit states and scores. Each analyzer/runtime probe emits Evidence documents; mitigations add Mitigation entries. The lattice engine joins both inputs into a ReachDecision:

UNOBSERVED (09)
    < POSSIBLE (1029)
        < STATIC_PATH (3059)
            < DYNAMIC_SEEN (6079)
                < DYNAMIC_USER_TAINTED (8099)
                    < EXPLOIT_CONSTRAINTS_REMOVED (100)

Each state corresponds to increasing confidence that a vulnerability can execute. Mitigations reduce scores; policy gates map scores to VEX statuses (not_affected, under_investigation, affected).


2. Core types

public enum ReachState { Unobserved, Possible, StaticPath, DynamicSeen, DynamicUserTainted, ExploitConstraintsRemoved }

public enum EvidenceKind {
    StaticCallEdge, StaticEntryPointProximity, StaticPackageDeclaredOnly,
    RuntimeMethodHit, RuntimeStackSample, RuntimeHttpRouteHit,
    UserInputSource, DataTaintFlow, ConfigFlagOn, ConfigFlagOff,
    ContainerNetworkRestricted, ContainerNetworkOpen,
    WafRulePresent, PatchLevel, VendorVexNotAffected, VendorVexAffected,
    ManualOverride
}

public sealed record Evidence(
    string Id,
    EvidenceKind Kind,
    double Weight,
    string Source,
    DateTimeOffset Timestamp,
    string? ArtifactRef,
    string? Details);

public enum MitigationKind { WafRule, FeatureFlagDisabled, AuthZEnforced, InputValidation, PatchedVersion, ContainerNetworkIsolation, RuntimeGuard, KillSwitch, Other }

public sealed record Mitigation(
    string Id,
    MitigationKind Kind,
    double Strength,
    string Source,
    DateTimeOffset Timestamp,
    string? ConfigHash,
    string? Details);

public sealed record ReachDecision(
    string VulnerabilityId,
    string ComponentPurl,
    ReachState State,
    int Score,
    string PolicyVersion,
    IReadOnlyList<Evidence> Evidence,
    IReadOnlyList<Mitigation> Mitigations,
    IReadOnlyDictionary<string,string> Metadata);

3. Scoring policy (default)

Evidence class Base score contribution
Static path (call graph) ≥ 30
Runtime hit ≥ 60
User-tainted flow ≥ 80
"Constraints removed" = 100
Lockfile-only evidence 10 (if no other signals)

Mitigations subtract up to 40 points (configurable):

effectiveScore = baseScore - min(sum(m.Strength), 1.0) * MaxMitigationDelta

Clamp final scores to 0100.


4. State & VEX gates

Default thresholds (edit in reachability.policy.yml):

State Score range
UNOBSERVED 09
POSSIBLE 1029
STATIC_PATH 3059
DYNAMIC_SEEN 6079
DYNAMIC_USER_TAINTED 8099
EXPLOIT_CONSTRAINTS_REMOVED 100

VEX mapping:

  • not_affected: score ≤ 25 or mitigations dominate (score reduced below threshold).
  • affected: score ≥ 60 (dynamic evidence without sufficient mitigation).
  • under_investigation: everything between. This explicit "Unknown" state is a key differentiator—incomplete data never leads to false safety.

Each decision records reachability.policy.version, analyzer versions, policy hash, and config snapshot so downstream verifiers can replay the exact logic. All decisions are sealed in Decision Capsules for audit-grade reproducibility.


5. Evidence sources

Signal group Producers EvidenceKind
Static call graph Roslyn/IL walkers, ASP.NET routing models, JVM/JIT analyzers StaticCallEdge, StaticEntryPointProximity, StaticFrameworkRouteEdge
Runtime sampling .NET EventPipe, JFR, Node inspector, Go/Rust probes RuntimeMethodHit, RuntimeStackSample, RuntimeHttpRouteHit
Data/taint Taint analyzers, user-input detectors UserInputSource, DataTaintFlow
Environment Config snapshot, container args, network policy ConfigFlagOn/Off, ContainerNetworkRestricted/Open
Mitigations WAF connectors, patch diff, kill switches MitigationKind.* via Mitigation records
Trust Vendor VEX statements, manual overrides VendorVexNotAffected/Affected, ManualOverride

Each evidence object must log Source, timestamps, and references (function IDs, config hashes) so auditors can trace it in the event graph. This enables evidence-linked VEX decisions where every assertion includes pointers to the underlying proof.


6. Event graph schema

Persist function-level edges and evidence in Mongo (or your event store) under:

  • reach_functions documents keyed by FunctionId.
  • reach_call_sites CallSite edges (caller, callee, frameworkEdge).
  • reach_evidence array of Evidence per (scanId, vulnId, component).
  • reach_mitigations array of Mitigation entries with config hashes.
  • reach_decisions final ReachDecision document; references above IDs.

All collections are tenant-scoped and include analyzer/policy version metadata.


7. Policy gates → VEX decisions

VEXer consumes ReachDecision and reachability.policy.yml to emit:

{
  "vulnerability": "CVE-2025-1234",
  "products": ["pkg:nuget/Example@1.2.3"],
  "status": "not_affected|under_investigation|affected",
  "status_notes": "Reachability score 22 (Possible) with WAF rule mitigation.",
  "justification": "component_not_present|vulnerable_code_not_present|... or custom reason",
  "action_statement": "Monitor config ABC",
  "impact_statement": "Runtime probes observed 0 hits; static call graph absent.",
  "timestamp": "...",
  "custom": {
    "reachability": {
      "state": "POSSIBLE",
      "score": 22,
      "policyVersion": "reach-1",
      "evidenceRefs": ["evidence:123", "mitigation:456"]
    }
  }
}

Justifications cite specific evidence/mitigation IDs so replay bundles (docs/replay/DETERMINISTIC_REPLAY.md) can prove the decision.


8. Runtime probes (overview)

  • .NET: EventPipe session watching Microsoft-Windows-DotNETRuntime/Loader,JITRuntimeMethodHit.
  • JVM: JFR recording with MethodProfilingSample events.
  • Node/TS: Inspector or --trace-event-categories node.async_hooks,node.perf sample.
  • Go/Rust: pprof/probe instrumentation.

All runtime probes write evidence via IRuntimeEvidenceSink, which deduplicates hits, enriches them with FunctionId, and stores them in reach_evidence.

See src/Scanner/StellaOps.Scanner.WebService/Reachability/Runtime/DotNetRuntimeProbe.cs (once implemented) for reference.


9. Hybrid Reachability

Stella Ops combines static call-graph analysis with runtime process tracing for true hybrid reachability:

  • Static analysis provides call-graph edges from IL/bytecode analysis, framework routing models, and entry-point proximity calculations.
  • Runtime analysis provides observed method hits, stack samples, and HTTP route hits from live or shadow traffic.
  • Hybrid reconciliation merges both signal types, with each edge type attestable via DSSE. See docs/reachability/hybrid-attestation.md for the attestation model.

This hybrid approach ensures that both build-time and run-time context contribute to the same verdict, avoiding the blind spots of purely static or purely runtime analysis.


10. Roadmap

Task Description
REACH-LATTICE-401-023 Initial lattice types + scoring engine + event graph schema.
REACH-RUNTIME-402-024 Productionize runtime probes (EventPipe/JFR) with opt-in config and telemetry.
REACH-VEX-402-025 Wire ReachDecision into VEX generator; ensure OpenVEX/CSAF cite reachability evidence.
REACH-POLICY-402-026 Expose reachability gates in Policy DSL & CLI (edit/lint/test).

Keep this doc updated as the lattice evolves or new signals/mitigations are added.