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

@@ -1,5 +1,6 @@
using System.Collections.ObjectModel;
using StellaOps.Auth.Abstractions;
using StellaOps.Policy.Engine.Telemetry;
namespace StellaOps.Policy.Engine.Options;
@@ -22,6 +23,10 @@ public sealed class PolicyEngineOptions
public PolicyEngineActivationOptions Activation { get; } = new();
public PolicyEngineTelemetryOptions Telemetry { get; } = new();
public PolicyEngineRiskProfileOptions RiskProfile { get; } = new();
public void Validate()
{
Authority.Validate();
@@ -30,6 +35,8 @@ public sealed class PolicyEngineOptions
ResourceServer.Validate();
Compilation.Validate();
Activation.Validate();
Telemetry.Validate();
RiskProfile.Validate();
}
}
@@ -225,3 +232,131 @@ public sealed class PolicyEngineActivationOptions
{
}
}
public sealed class PolicyEngineRiskProfileOptions
{
/// <summary>
/// Enables risk profile integration for policy evaluation.
/// </summary>
public bool Enabled { get; set; } = true;
/// <summary>
/// Default profile ID to use when no profile is specified.
/// </summary>
public string DefaultProfileId { get; set; } = "default";
/// <summary>
/// Directory containing risk profile JSON files.
/// </summary>
public string? ProfileDirectory { get; set; }
/// <summary>
/// Maximum inheritance depth for profile resolution.
/// </summary>
public int MaxInheritanceDepth { get; set; } = 10;
/// <summary>
/// Whether to validate profiles against the JSON schema on load.
/// </summary>
public bool ValidateOnLoad { get; set; } = true;
/// <summary>
/// Whether to cache resolved profiles in memory.
/// </summary>
public bool CacheResolvedProfiles { get; set; } = true;
/// <summary>
/// Inline profile definitions (for config-based profiles).
/// </summary>
public List<RiskProfileDefinition> Profiles { get; } = new();
public void Validate()
{
if (MaxInheritanceDepth <= 0)
{
throw new InvalidOperationException("RiskProfile.MaxInheritanceDepth must be greater than zero.");
}
if (string.IsNullOrWhiteSpace(DefaultProfileId))
{
throw new InvalidOperationException("RiskProfile.DefaultProfileId is required.");
}
}
}
/// <summary>
/// Inline risk profile definition in configuration.
/// </summary>
public sealed class RiskProfileDefinition
{
/// <summary>
/// Profile identifier.
/// </summary>
public required string Id { get; set; }
/// <summary>
/// Profile version (SemVer).
/// </summary>
public required string Version { get; set; }
/// <summary>
/// Human-readable description.
/// </summary>
public string? Description { get; set; }
/// <summary>
/// Parent profile ID for inheritance.
/// </summary>
public string? Extends { get; set; }
/// <summary>
/// Signal definitions for risk scoring.
/// </summary>
public List<RiskProfileSignalDefinition> Signals { get; } = new();
/// <summary>
/// Weight per signal name.
/// </summary>
public Dictionary<string, double> Weights { get; } = new();
/// <summary>
/// Optional metadata.
/// </summary>
public Dictionary<string, object?>? Metadata { get; set; }
}
/// <summary>
/// Inline signal definition in configuration.
/// </summary>
public sealed class RiskProfileSignalDefinition
{
/// <summary>
/// Signal name.
/// </summary>
public required string Name { get; set; }
/// <summary>
/// Signal source.
/// </summary>
public required string Source { get; set; }
/// <summary>
/// Signal type (boolean, numeric, categorical).
/// </summary>
public required string Type { get; set; }
/// <summary>
/// JSON Pointer path in evidence.
/// </summary>
public string? Path { get; set; }
/// <summary>
/// Optional transform expression.
/// </summary>
public string? Transform { get; set; }
/// <summary>
/// Optional unit for numeric signals.
/// </summary>
public string? Unit { get; set; }
}