up
Some checks failed
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Policy Simulation / policy-simulate (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled
Signals Reachability Scoring & Events / reachability-smoke (push) Has been cancelled
Signals Reachability Scoring & Events / sign-and-upload (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled

This commit is contained in:
StellaOps Bot
2025-12-13 09:37:15 +02:00
parent e00f6365da
commit 6e45066e37
349 changed files with 17160 additions and 1867 deletions

View File

@@ -13,6 +13,7 @@ using StellaOps.Attestor.Core.Storage;
using StellaOps.Attestor.Core.Submission;
using StellaOps.Attestor.Core.Transparency;
using StellaOps.Attestor.Core.Verification;
using StellaOps.Attestor.Core.Bulk;
using StellaOps.Attestor.Infrastructure.Rekor;
using StellaOps.Attestor.Infrastructure.Storage;
using StellaOps.Attestor.Infrastructure.Submission;

View File

@@ -13,6 +13,7 @@
<ProjectReference Include="..\..\..\__Libraries\StellaOps.Cryptography.Plugin.BouncyCastle\StellaOps.Cryptography.Plugin.BouncyCastle.csproj" />
<ProjectReference Include="..\..\..\__Libraries\StellaOps.Cryptography.Kms\StellaOps.Cryptography.Kms.csproj" />
<ProjectReference Include="..\..\..\__Libraries\StellaOps.Cryptography.Plugin.SmSoft\StellaOps.Cryptography.Plugin.SmSoft.csproj" />
<ProjectReference Include="..\..\..\__Libraries\StellaOps.Messaging\StellaOps.Messaging.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.0" />

View File

@@ -0,0 +1,107 @@
using System;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using StellaOps.Attestor.Core.Options;
using StellaOps.Attestor.Core.Verification;
using StellaOps.Messaging;
using StellaOps.Messaging.Abstractions;
namespace StellaOps.Attestor.Infrastructure.Verification;
/// <summary>
/// Attestor verification cache backed by <see cref="IDistributedCache{TValue}"/>.
/// Supports any transport (InMemory, Valkey, PostgreSQL) via factory injection.
/// </summary>
internal sealed class MessagingAttestorVerificationCache : IAttestorVerificationCache
{
private readonly IDistributedCache<AttestorVerificationResult> _cache;
private readonly ILogger<MessagingAttestorVerificationCache> _logger;
private readonly TimeSpan _ttl;
public MessagingAttestorVerificationCache(
IDistributedCacheFactory cacheFactory,
IOptions<AttestorOptions> options,
ILogger<MessagingAttestorVerificationCache> logger)
{
ArgumentNullException.ThrowIfNull(cacheFactory);
ArgumentNullException.ThrowIfNull(options);
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
var ttlSeconds = Math.Max(1, options.Value.Cache.Verification.TtlSeconds);
_ttl = TimeSpan.FromSeconds(ttlSeconds);
_cache = cacheFactory.Create<AttestorVerificationResult>(new CacheOptions
{
KeyPrefix = "attestor:verify:",
DefaultTtl = _ttl,
});
_logger.LogInformation(
"Initialized MessagingAttestorVerificationCache with provider {Provider}, TTL {Ttl}s",
_cache.ProviderName,
_ttl.TotalSeconds.ToString(CultureInfo.InvariantCulture));
}
public async Task<AttestorVerificationResult?> GetAsync(
string subject,
string envelopeId,
string policyVersion,
CancellationToken cancellationToken = default)
{
var cacheKey = BuildCacheKey(subject, envelopeId, policyVersion);
var result = await _cache.GetAsync(cacheKey, cancellationToken).ConfigureAwait(false);
if (result.HasValue)
{
return result.Value;
}
return null;
}
public async Task SetAsync(
string subject,
string envelopeId,
string policyVersion,
AttestorVerificationResult result,
CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(result);
var cacheKey = BuildCacheKey(subject, envelopeId, policyVersion);
var entryOptions = new CacheEntryOptions { TimeToLive = _ttl };
await _cache.SetAsync(cacheKey, result, entryOptions, cancellationToken).ConfigureAwait(false);
var subjectKey = Normalize(subject);
_logger.LogDebug(
"Cached verification result for subject {Subject} envelope {Envelope} policy {Policy} with TTL {TtlSeconds}s.",
subjectKey,
Normalize(envelopeId),
Normalize(policyVersion),
_ttl.TotalSeconds.ToString(CultureInfo.InvariantCulture));
}
public async Task InvalidateSubjectAsync(string subject, CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(subject))
{
return;
}
var subjectKey = Normalize(subject);
// Pattern: attestor:verify:<subject>|*
var pattern = $"{subjectKey}|*";
var count = await _cache.InvalidateByPatternAsync(pattern, cancellationToken).ConfigureAwait(false);
_logger.LogDebug("Invalidated {Count} verification cache entries for subject {Subject}.", count, subjectKey);
}
private static string BuildCacheKey(string subject, string envelopeId, string policyVersion) =>
string.Concat(Normalize(subject), "|", Normalize(envelopeId), "|", Normalize(policyVersion));
private static string Normalize(string? value) => (value ?? string.Empty).Trim();
}