partly or unimplemented features - now implemented
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# StellaOps.Scanner.Gate Task Board
|
||||
# StellaOps.Scanner.Gate Task Board
|
||||
This board mirrors active sprint tasks for this module.
|
||||
Source of truth: `docs/implplan/SPRINT_20260130_002_Tools_csproj_remediation_solid_review.md`.
|
||||
|
||||
@@ -6,3 +6,5 @@ Source of truth: `docs/implplan/SPRINT_20260130_002_Tools_csproj_remediation_sol
|
||||
| --- | --- | --- |
|
||||
| REMED-05 | TODO | Remediation checklist: docs/implplan/audits/csproj-standards/remediation/checklists/src/Scanner/__Libraries/StellaOps.Scanner.Gate/StellaOps.Scanner.Gate.md. |
|
||||
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |
|
||||
| SPRINT-20260208-062-VEXREACH-001 | DONE | Implemented dedicated VEX+reachability decision matrix filter with deterministic action/effective-decision mapping (2026-02-08). |
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ public static class VexGateServiceCollectionExtensions
|
||||
|
||||
// Register VEX gate service
|
||||
services.AddSingleton<IVexGateService, VexGateService>();
|
||||
services.AddSingleton<IVexReachabilityDecisionFilter, VexReachabilityDecisionFilter>();
|
||||
|
||||
return services;
|
||||
}
|
||||
@@ -122,6 +123,7 @@ public static class VexGateServiceCollectionExtensions
|
||||
|
||||
// Register VEX gate service
|
||||
services.AddSingleton<IVexGateService, VexGateService>();
|
||||
services.AddSingleton<IVexReachabilityDecisionFilter, VexReachabilityDecisionFilter>();
|
||||
|
||||
return services;
|
||||
}
|
||||
@@ -163,6 +165,7 @@ public static class VexGateServiceCollectionExtensions
|
||||
|
||||
// Register VEX gate service
|
||||
services.AddSingleton<IVexGateService, VexGateService>();
|
||||
services.AddSingleton<IVexReachabilityDecisionFilter, VexReachabilityDecisionFilter>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// VexReachabilityDecisionFilter.cs
|
||||
// Sprint: SPRINT_20260208_062_Scanner_vex_decision_filter_with_reachability
|
||||
// Description: Deterministic matrix filter that combines VEX status and reachability.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace StellaOps.Scanner.Gate;
|
||||
|
||||
/// <summary>
|
||||
/// Filters findings using a deterministic (VEX status x reachability tier) decision matrix.
|
||||
/// </summary>
|
||||
public interface IVexReachabilityDecisionFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// Evaluates a single finding and returns the annotated decision.
|
||||
/// </summary>
|
||||
VexReachabilityDecisionResult Evaluate(VexReachabilityDecisionInput input);
|
||||
|
||||
/// <summary>
|
||||
/// Evaluates a batch of findings in stable input order.
|
||||
/// </summary>
|
||||
ImmutableArray<VexReachabilityDecisionResult> EvaluateBatch(IReadOnlyList<VexReachabilityDecisionInput> inputs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reachability confidence tier used for VEX-aware filtering.
|
||||
/// </summary>
|
||||
public enum VexReachabilityTier
|
||||
{
|
||||
Confirmed,
|
||||
Likely,
|
||||
Present,
|
||||
Unreachable,
|
||||
Unknown
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filter action after matrix evaluation.
|
||||
/// </summary>
|
||||
public enum VexReachabilityFilterAction
|
||||
{
|
||||
Suppress,
|
||||
Elevate,
|
||||
PassThrough,
|
||||
FlagForReview
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Input for VEX + reachability matrix evaluation.
|
||||
/// </summary>
|
||||
public sealed record VexReachabilityDecisionInput
|
||||
{
|
||||
public required string FindingId { get; init; }
|
||||
public required string VulnerabilityId { get; init; }
|
||||
public string? Purl { get; init; }
|
||||
public VexStatus? VendorStatus { get; init; }
|
||||
public VexReachabilityTier ReachabilityTier { get; init; } = VexReachabilityTier.Unknown;
|
||||
public VexGateDecision ExistingDecision { get; init; } = VexGateDecision.Warn;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Output from VEX + reachability matrix evaluation.
|
||||
/// </summary>
|
||||
public sealed record VexReachabilityDecisionResult
|
||||
{
|
||||
public required string FindingId { get; init; }
|
||||
public required string VulnerabilityId { get; init; }
|
||||
public string? Purl { get; init; }
|
||||
public VexStatus? VendorStatus { get; init; }
|
||||
public VexReachabilityTier ReachabilityTier { get; init; }
|
||||
public VexReachabilityFilterAction Action { get; init; }
|
||||
public VexGateDecision EffectiveDecision { get; init; }
|
||||
public required string Rationale { get; init; }
|
||||
public required string MatrixRule { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default deterministic implementation of <see cref="IVexReachabilityDecisionFilter"/>.
|
||||
/// </summary>
|
||||
public sealed class VexReachabilityDecisionFilter : IVexReachabilityDecisionFilter
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public VexReachabilityDecisionResult Evaluate(VexReachabilityDecisionInput input)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(input);
|
||||
|
||||
var (action, rule, rationale) = EvaluateMatrix(input.VendorStatus, input.ReachabilityTier);
|
||||
var effectiveDecision = action switch
|
||||
{
|
||||
VexReachabilityFilterAction.Suppress => VexGateDecision.Pass,
|
||||
VexReachabilityFilterAction.Elevate => VexGateDecision.Block,
|
||||
VexReachabilityFilterAction.FlagForReview => VexGateDecision.Warn,
|
||||
_ => input.ExistingDecision
|
||||
};
|
||||
|
||||
return new VexReachabilityDecisionResult
|
||||
{
|
||||
FindingId = input.FindingId,
|
||||
VulnerabilityId = input.VulnerabilityId,
|
||||
Purl = input.Purl,
|
||||
VendorStatus = input.VendorStatus,
|
||||
ReachabilityTier = input.ReachabilityTier,
|
||||
Action = action,
|
||||
EffectiveDecision = effectiveDecision,
|
||||
Rationale = rationale,
|
||||
MatrixRule = rule
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ImmutableArray<VexReachabilityDecisionResult> EvaluateBatch(IReadOnlyList<VexReachabilityDecisionInput> inputs)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(inputs);
|
||||
|
||||
if (inputs.Count == 0)
|
||||
{
|
||||
return ImmutableArray<VexReachabilityDecisionResult>.Empty;
|
||||
}
|
||||
|
||||
var builder = ImmutableArray.CreateBuilder<VexReachabilityDecisionResult>(inputs.Count);
|
||||
for (var i = 0; i < inputs.Count; i++)
|
||||
{
|
||||
builder.Add(Evaluate(inputs[i]));
|
||||
}
|
||||
|
||||
return builder.MoveToImmutable();
|
||||
}
|
||||
|
||||
private static (VexReachabilityFilterAction Action, string Rule, string Rationale) EvaluateMatrix(
|
||||
VexStatus? vendorStatus,
|
||||
VexReachabilityTier tier)
|
||||
{
|
||||
if (vendorStatus == VexStatus.NotAffected && tier == VexReachabilityTier.Unreachable)
|
||||
{
|
||||
return (
|
||||
VexReachabilityFilterAction.Suppress,
|
||||
"not_affected+unreachable",
|
||||
"Suppress: vendor reports not_affected and reachability is unreachable.");
|
||||
}
|
||||
|
||||
if (vendorStatus == VexStatus.Affected &&
|
||||
(tier == VexReachabilityTier.Confirmed || tier == VexReachabilityTier.Likely))
|
||||
{
|
||||
return (
|
||||
VexReachabilityFilterAction.Elevate,
|
||||
"affected+reachable",
|
||||
"Elevate: vendor reports affected and reachability indicates impact.");
|
||||
}
|
||||
|
||||
if (vendorStatus == VexStatus.NotAffected &&
|
||||
(tier == VexReachabilityTier.Confirmed || tier == VexReachabilityTier.Likely))
|
||||
{
|
||||
return (
|
||||
VexReachabilityFilterAction.FlagForReview,
|
||||
"not_affected+reachable",
|
||||
"Flag for review: VEX not_affected conflicts with reachable evidence.");
|
||||
}
|
||||
|
||||
if (vendorStatus == VexStatus.Fixed &&
|
||||
(tier == VexReachabilityTier.Confirmed || tier == VexReachabilityTier.Likely))
|
||||
{
|
||||
return (
|
||||
VexReachabilityFilterAction.FlagForReview,
|
||||
"fixed+reachable",
|
||||
"Flag for review: fixed status conflicts with reachable evidence.");
|
||||
}
|
||||
|
||||
if (vendorStatus == VexStatus.UnderInvestigation && tier == VexReachabilityTier.Confirmed)
|
||||
{
|
||||
return (
|
||||
VexReachabilityFilterAction.Elevate,
|
||||
"under_investigation+confirmed",
|
||||
"Elevate: confirmed reachability while vendor status remains under investigation.");
|
||||
}
|
||||
|
||||
return (
|
||||
VexReachabilityFilterAction.PassThrough,
|
||||
"default-pass-through",
|
||||
"Pass through: no override matrix rule matched.");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user