Implement VEX document verification system with issuer management and signature verification

- Added IIssuerDirectory interface for managing VEX document issuers, including methods for registration, revocation, and trust validation.
- Created InMemoryIssuerDirectory class as an in-memory implementation of IIssuerDirectory for testing and single-instance deployments.
- Introduced ISignatureVerifier interface for verifying signatures on VEX documents, with support for multiple signature formats.
- Developed SignatureVerifier class as the default implementation of ISignatureVerifier, allowing extensibility for different signature formats.
- Implemented handlers for DSSE and JWS signature formats, including methods for verification and signature extraction.
- Defined various records and enums for issuer and signature metadata, enhancing the structure and clarity of the verification process.
This commit is contained in:
StellaOps Bot
2025-12-06 13:41:22 +02:00
parent 2141196496
commit 5e514532df
112 changed files with 24861 additions and 211 deletions

View File

@@ -585,6 +585,72 @@ public static class PolicyEngineTelemetry
#endregion
#region AirGap/Staleness Metrics
// Counter: policy_airgap_staleness_events_total{tenant,event_type}
private static readonly Counter<long> StalenessEventsCounter =
Meter.CreateCounter<long>(
"policy_airgap_staleness_events_total",
unit: "events",
description: "Total staleness events by type (warning, breach, recovered, anchor_missing).");
// Gauge: policy_airgap_sealed
private static readonly ObservableGauge<int> AirGapSealedGauge =
Meter.CreateObservableGauge<int>(
"policy_airgap_sealed",
observeValues: () => AirGapSealedObservations ?? Enumerable.Empty<Measurement<int>>(),
unit: "boolean",
description: "1 if sealed, 0 if unsealed.");
// Gauge: policy_airgap_anchor_age_seconds
private static readonly ObservableGauge<int> AnchorAgeGauge =
Meter.CreateObservableGauge<int>(
"policy_airgap_anchor_age_seconds",
observeValues: () => AnchorAgeObservations ?? Enumerable.Empty<Measurement<int>>(),
unit: "s",
description: "Current age of the time anchor in seconds.");
private static IEnumerable<Measurement<int>> AirGapSealedObservations = Enumerable.Empty<Measurement<int>>();
private static IEnumerable<Measurement<int>> AnchorAgeObservations = Enumerable.Empty<Measurement<int>>();
/// <summary>
/// Records a staleness event.
/// </summary>
/// <param name="tenant">Tenant identifier.</param>
/// <param name="eventType">Event type (warning, breach, recovered, anchor_missing).</param>
public static void RecordStalenessEvent(string tenant, string eventType)
{
var tags = new TagList
{
{ "tenant", NormalizeTenant(tenant) },
{ "event_type", NormalizeTag(eventType) },
};
StalenessEventsCounter.Add(1, tags);
}
/// <summary>
/// Registers a callback to observe air-gap sealed state.
/// </summary>
/// <param name="observeFunc">Function that returns current sealed state measurements.</param>
public static void RegisterAirGapSealedObservation(Func<IEnumerable<Measurement<int>>> observeFunc)
{
ArgumentNullException.ThrowIfNull(observeFunc);
AirGapSealedObservations = observeFunc();
}
/// <summary>
/// Registers a callback to observe time anchor age.
/// </summary>
/// <param name="observeFunc">Function that returns current anchor age measurements.</param>
public static void RegisterAnchorAgeObservation(Func<IEnumerable<Measurement<int>>> observeFunc)
{
ArgumentNullException.ThrowIfNull(observeFunc);
AnchorAgeObservations = observeFunc();
}
#endregion
// Storage for observable gauge observations
private static IEnumerable<Measurement<int>> QueueDepthObservations = Enumerable.Empty<Measurement<int>>();
private static IEnumerable<Measurement<int>> ConcurrentEvaluationsObservations = Enumerable.Empty<Measurement<int>>();