- Introduced a new document outlining the inline DSSE provenance for SBOM, VEX, scan, and derived events. - Defined the Mongo schema for event patches, including key fields for provenance and trust verification. - Documented the write path for ingesting provenance metadata and backfilling historical events. - Created CI/CD snippets for uploading DSSE attestations and generating provenance metadata. - Established Mongo indexes for efficient provenance queries and provided query recipes for various use cases. - Outlined policy gates for managing VEX decisions based on provenance verification. - Included UI nudges for displaying provenance information and implementation tasks for future enhancements. --- Implement reachability lattice and scoring model - Developed a comprehensive document detailing the reachability lattice and scoring model. - Defined core types for reachability states, evidence, and mitigations with corresponding C# models. - Established a scoring policy with base score contributions from various evidence classes. - Mapped reachability states to VEX gates and provided a clear overview of evidence sources. - Documented the event graph schema for persisting reachability data in MongoDB. - Outlined the integration of runtime probes for evidence collection and defined a roadmap for future tasks. --- Introduce uncertainty states and entropy scoring - Created a draft document for tracking uncertainty states and their impact on risk scoring. - Defined core uncertainty states with associated entropy values and evidence requirements. - Established a schema for storing uncertainty states alongside findings. - Documented the risk score calculation incorporating uncertainty and its effect on final risk assessments. - Provided policy guidelines for handling uncertainty in decision-making processes. - Outlined UI guidelines for displaying uncertainty information and suggested remediation actions. --- Add Ruby package inventory management - Implemented Ruby package inventory management with corresponding data models and storage mechanisms. - Created C# records for Ruby package inventory, artifacts, provenance, and runtime details. - Developed a repository for managing Ruby package inventory documents in MongoDB. - Implemented a service for storing and retrieving Ruby package inventories. - Added unit tests for the Ruby package inventory store to ensure functionality and data integrity.
7.5 KiB
Reachability Lattice & Scoring Model
Status: Draft – mirrors the November 2025 advisory on confidence-based reachability.
Owners: Scanner Guild · Policy Guild · Signals Guild.
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
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 (0–9)
< POSSIBLE (10–29)
< STATIC_PATH (30–59)
< DYNAMIC_SEEN (60–79)
< DYNAMIC_USER_TAINTED (80–99)
< 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 0–100.
4. State & VEX gates
Default thresholds (edit in reachability.policy.yml):
| State | Score range |
|---|---|
| UNOBSERVED | 0–9 |
| POSSIBLE | 10–29 |
| STATIC_PATH | 30–59 |
| DYNAMIC_SEEN | 60–79 |
| DYNAMIC_USER_TAINTED | 80–99 |
| 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.
Each decision records reachability.policy.version, analyzer versions, policy hash, and config snapshot so downstream verifiers can replay the exact logic.
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.
6. Event graph schema
Persist function-level edges and evidence in Mongo (or your event store) under:
reach_functions– documents keyed byFunctionId.reach_call_sites–CallSiteedges (caller,callee,frameworkEdge).reach_evidence– array ofEvidenceper(scanId, vulnId, component).reach_mitigations– array ofMitigationentries with config hashes.reach_decisions– finalReachDecisiondocument; 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,JIT→RuntimeMethodHit. - JVM: JFR recording with
MethodProfilingSampleevents. - Node/TS: Inspector or
--trace-event-categories node.async_hooks,node.perfsample. - 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. 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. *** End Patch