Fix build and code structure improvements. New but essential UI functionality. CI improvements. Documentation improvements. AI module improvements.
This commit is contained in:
@@ -0,0 +1,204 @@
|
||||
// VexTrustConfidenceFactorProvider - Confidence factor from VEX trust data
|
||||
// Part of SPRINT_1227_0004_0003: VexTrustGate Policy Integration
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using StellaOps.Policy.Confidence.Models;
|
||||
using StellaOps.Policy.Engine.Gates;
|
||||
|
||||
namespace StellaOps.Policy.Engine.Confidence;
|
||||
|
||||
/// <summary>
|
||||
/// Interface for providers that contribute confidence factors.
|
||||
/// </summary>
|
||||
public interface IConfidenceFactorProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of confidence factor this provider produces.
|
||||
/// </summary>
|
||||
ConfidenceFactorType Type { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Compute a confidence factor from available context.
|
||||
/// Returns null if insufficient data to compute.
|
||||
/// </summary>
|
||||
ConfidenceFactor? ComputeFactor(
|
||||
ConfidenceFactorContext context,
|
||||
ConfidenceFactorOptions options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Context for confidence factor computation.
|
||||
/// </summary>
|
||||
public sealed record ConfidenceFactorContext
|
||||
{
|
||||
/// <summary>
|
||||
/// VEX trust status from signature verification.
|
||||
/// </summary>
|
||||
public VexTrustStatus? VexTrustStatus { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Environment (production, staging, development).
|
||||
/// </summary>
|
||||
public string? Environment { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Tenant identifier.
|
||||
/// </summary>
|
||||
public string? TenantId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// CVE or vulnerability identifier.
|
||||
/// </summary>
|
||||
public string? VulnerabilityId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Product/component identifier.
|
||||
/// </summary>
|
||||
public string? ProductId { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Options for confidence factor computation.
|
||||
/// </summary>
|
||||
public sealed record ConfidenceFactorOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Weight to assign to VEX trust factor.
|
||||
/// </summary>
|
||||
public decimal VexTrustWeight { get; init; } = 0.20m;
|
||||
|
||||
/// <summary>
|
||||
/// Minimum trust score to contribute positively.
|
||||
/// </summary>
|
||||
public decimal MinTrustScoreContribution { get; init; } = 0.30m;
|
||||
|
||||
/// <summary>
|
||||
/// Bonus for signature verification.
|
||||
/// </summary>
|
||||
public decimal SignatureVerifiedBonus { get; init; } = 0.10m;
|
||||
|
||||
/// <summary>
|
||||
/// Bonus for Rekor transparency.
|
||||
/// </summary>
|
||||
public decimal TransparencyBonus { get; init; } = 0.05m;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes VEX trust confidence factor from signature verification results.
|
||||
/// </summary>
|
||||
public sealed class VexTrustConfidenceFactorProvider : IConfidenceFactorProvider
|
||||
{
|
||||
public ConfidenceFactorType Type => ConfidenceFactorType.Vex;
|
||||
|
||||
/// <inheritdoc />
|
||||
public ConfidenceFactor? ComputeFactor(
|
||||
ConfidenceFactorContext context,
|
||||
ConfidenceFactorOptions options)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(context);
|
||||
ArgumentNullException.ThrowIfNull(options);
|
||||
|
||||
var trustStatus = context.VexTrustStatus;
|
||||
|
||||
// No trust status means we can't contribute a factor
|
||||
if (trustStatus is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var score = trustStatus.TrustScore;
|
||||
var tier = ComputeTier(score);
|
||||
|
||||
// Apply bonuses for verification and transparency
|
||||
var adjustedScore = score;
|
||||
|
||||
if (trustStatus.SignatureVerified == true)
|
||||
{
|
||||
adjustedScore += options.SignatureVerifiedBonus;
|
||||
}
|
||||
|
||||
if (trustStatus.RekorLogIndex.HasValue)
|
||||
{
|
||||
adjustedScore += options.TransparencyBonus;
|
||||
}
|
||||
|
||||
// Clamp to [0, 1]
|
||||
adjustedScore = Math.Clamp(adjustedScore, 0m, 1m);
|
||||
|
||||
return new ConfidenceFactor
|
||||
{
|
||||
Type = ConfidenceFactorType.Vex,
|
||||
Weight = options.VexTrustWeight,
|
||||
RawValue = adjustedScore,
|
||||
Reason = BuildReason(trustStatus, tier),
|
||||
EvidenceDigests = BuildEvidenceDigests(trustStatus)
|
||||
};
|
||||
}
|
||||
|
||||
private static string ComputeTier(decimal score)
|
||||
{
|
||||
return score switch
|
||||
{
|
||||
>= 0.9m => "VeryHigh",
|
||||
>= 0.7m => "High",
|
||||
>= 0.5m => "Medium",
|
||||
>= 0.3m => "Low",
|
||||
_ => "VeryLow"
|
||||
};
|
||||
}
|
||||
|
||||
private static string BuildReason(VexTrustStatus status, string tier)
|
||||
{
|
||||
var parts = new List<string>
|
||||
{
|
||||
$"VEX trust: {tier} ({status.TrustScore:P0})"
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(status.IssuerName))
|
||||
{
|
||||
parts.Add($"issuer: {status.IssuerName}");
|
||||
}
|
||||
|
||||
if (status.SignatureVerified == true)
|
||||
{
|
||||
parts.Add("signature verified");
|
||||
|
||||
if (!string.IsNullOrEmpty(status.SignatureMethod))
|
||||
{
|
||||
parts.Add($"method: {status.SignatureMethod}");
|
||||
}
|
||||
}
|
||||
|
||||
if (status.RekorLogIndex.HasValue)
|
||||
{
|
||||
parts.Add($"Rekor: #{status.RekorLogIndex}");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(status.Freshness))
|
||||
{
|
||||
parts.Add($"freshness: {status.Freshness}");
|
||||
}
|
||||
|
||||
return string.Join("; ", parts);
|
||||
}
|
||||
|
||||
private static IReadOnlyList<string> BuildEvidenceDigests(VexTrustStatus status)
|
||||
{
|
||||
var digests = new List<string>();
|
||||
|
||||
// Add Rekor log info as an evidence reference
|
||||
if (!string.IsNullOrEmpty(status.RekorLogId) && status.RekorLogIndex.HasValue)
|
||||
{
|
||||
digests.Add($"rekor:{status.RekorLogId}@{status.RekorLogIndex}");
|
||||
}
|
||||
|
||||
// Add issuer reference
|
||||
if (!string.IsNullOrEmpty(status.IssuerId))
|
||||
{
|
||||
digests.Add($"issuer:{status.IssuerId}");
|
||||
}
|
||||
|
||||
return digests;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user