up
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
api-governance / spectral-lint (push) Has been cancelled
oas-ci / oas-validate (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Policy Simulation / policy-simulate (push) Has been cancelled
SDK Publish & Sign / sdk-publish (push) Has been cancelled

This commit is contained in:
master
2025-11-27 15:05:48 +02:00
parent 4831c7fcb0
commit e950474a77
278 changed files with 81498 additions and 672 deletions

View File

@@ -0,0 +1,213 @@
using System.Text.Json.Serialization;
namespace StellaOps.Policy.RiskProfile.Models;
/// <summary>
/// Represents a risk profile definition used to score and prioritize findings.
/// </summary>
public sealed class RiskProfileModel
{
/// <summary>
/// Stable identifier for the risk profile (slug or URN).
/// </summary>
[JsonPropertyName("id")]
public required string Id { get; set; }
/// <summary>
/// SemVer for the profile definition.
/// </summary>
[JsonPropertyName("version")]
public required string Version { get; set; }
/// <summary>
/// Human-readable summary of the profile intent.
/// </summary>
[JsonPropertyName("description")]
public string? Description { get; set; }
/// <summary>
/// Optional parent profile ID for inheritance.
/// </summary>
[JsonPropertyName("extends")]
public string? Extends { get; set; }
/// <summary>
/// Signal definitions used for risk scoring.
/// </summary>
[JsonPropertyName("signals")]
public List<RiskSignal> Signals { get; set; } = new();
/// <summary>
/// Weight per signal name; weights are normalized by the consumer.
/// </summary>
[JsonPropertyName("weights")]
public Dictionary<string, double> Weights { get; set; } = new();
/// <summary>
/// Override rules for severity and decisions.
/// </summary>
[JsonPropertyName("overrides")]
public RiskOverrides Overrides { get; set; } = new();
/// <summary>
/// Free-form metadata with stable keys.
/// </summary>
[JsonPropertyName("metadata")]
public Dictionary<string, object?>? Metadata { get; set; }
}
/// <summary>
/// A signal definition used in risk scoring.
/// </summary>
public sealed class RiskSignal
{
/// <summary>
/// Logical signal key (e.g., reachability, kev, exploit_chain).
/// </summary>
[JsonPropertyName("name")]
public required string Name { get; set; }
/// <summary>
/// Upstream provider or calculation origin.
/// </summary>
[JsonPropertyName("source")]
public required string Source { get; set; }
/// <summary>
/// Signal type.
/// </summary>
[JsonPropertyName("type")]
public required RiskSignalType Type { get; set; }
/// <summary>
/// JSON Pointer to the signal in the evidence document.
/// </summary>
[JsonPropertyName("path")]
public string? Path { get; set; }
/// <summary>
/// Optional transform applied before weighting.
/// </summary>
[JsonPropertyName("transform")]
public string? Transform { get; set; }
/// <summary>
/// Optional unit for numeric signals.
/// </summary>
[JsonPropertyName("unit")]
public string? Unit { get; set; }
}
/// <summary>
/// Signal type enumeration.
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter<RiskSignalType>))]
public enum RiskSignalType
{
[JsonPropertyName("boolean")]
Boolean,
[JsonPropertyName("numeric")]
Numeric,
[JsonPropertyName("categorical")]
Categorical,
}
/// <summary>
/// Override rules for severity and decisions.
/// </summary>
public sealed class RiskOverrides
{
/// <summary>
/// Severity override rules.
/// </summary>
[JsonPropertyName("severity")]
public List<SeverityOverride> Severity { get; set; } = new();
/// <summary>
/// Decision override rules.
/// </summary>
[JsonPropertyName("decisions")]
public List<DecisionOverride> Decisions { get; set; } = new();
}
/// <summary>
/// A severity override rule.
/// </summary>
public sealed class SeverityOverride
{
/// <summary>
/// Predicate over signals (key/value equals).
/// </summary>
[JsonPropertyName("when")]
public required Dictionary<string, object> When { get; set; }
/// <summary>
/// Severity to set when predicate matches.
/// </summary>
[JsonPropertyName("set")]
public required RiskSeverity Set { get; set; }
}
/// <summary>
/// A decision override rule.
/// </summary>
public sealed class DecisionOverride
{
/// <summary>
/// Predicate over signals (key/value equals).
/// </summary>
[JsonPropertyName("when")]
public required Dictionary<string, object> When { get; set; }
/// <summary>
/// Action to take when predicate matches.
/// </summary>
[JsonPropertyName("action")]
public required RiskAction Action { get; set; }
/// <summary>
/// Optional reason for the override.
/// </summary>
[JsonPropertyName("reason")]
public string? Reason { get; set; }
}
/// <summary>
/// Severity levels.
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter<RiskSeverity>))]
public enum RiskSeverity
{
[JsonPropertyName("critical")]
Critical,
[JsonPropertyName("high")]
High,
[JsonPropertyName("medium")]
Medium,
[JsonPropertyName("low")]
Low,
[JsonPropertyName("informational")]
Informational,
}
/// <summary>
/// Decision actions.
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter<RiskAction>))]
public enum RiskAction
{
[JsonPropertyName("allow")]
Allow,
[JsonPropertyName("review")]
Review,
[JsonPropertyName("deny")]
Deny,
}