Close admin trust audit gaps and stabilize live sweeps

This commit is contained in:
master
2026-03-12 10:14:00 +02:00
parent a00efb7ab2
commit 6964a046a5
50 changed files with 5968 additions and 2850 deletions

View File

@@ -223,11 +223,29 @@ public static class PackAdapterEndpoints
.WithSummary("Pack v2 administration A5 policy governance projection.")
.RequireAuthorization(PlatformPolicies.SetupRead);
administration.MapGet("/trust-signing", (
administration.MapGet("/trust-signing", async (
HttpContext context,
PlatformRequestContextResolver resolver) =>
PlatformRequestContextResolver resolver,
IAdministrationTrustSigningStore trustSigningStore,
CancellationToken cancellationToken) =>
{
return BuildAdministrationItem(context, resolver, BuildAdministrationTrustSigning);
if (!TryResolveContext(context, resolver, out var requestContext, out var failure))
{
return failure!;
}
var payload = await BuildAdministrationTrustSigningAsync(
requestContext!.TenantId,
trustSigningStore,
cancellationToken).ConfigureAwait(false);
return Results.Ok(new PlatformItemResponse<AdministrationTrustSigningDto>(
requestContext.TenantId,
requestContext.ActorId,
SnapshotAt,
Cached: false,
CacheTtlSeconds: 0,
payload));
})
.WithName("GetAdministrationTrustSigning")
.WithSummary("Pack v2 administration A6 trust and signing projection.")
@@ -540,14 +558,41 @@ public static class PackAdapterEndpoints
]);
}
private static AdministrationTrustSigningDto BuildAdministrationTrustSigning()
private static async Task<AdministrationTrustSigningDto> BuildAdministrationTrustSigningAsync(
string tenantId,
IAdministrationTrustSigningStore trustSigningStore,
CancellationToken cancellationToken)
{
var keys = await trustSigningStore.ListKeysAsync(tenantId, 500, 0, cancellationToken).ConfigureAwait(false);
var issuers = await trustSigningStore.ListIssuersAsync(tenantId, 500, 0, cancellationToken).ConfigureAwait(false);
var certificates = await trustSigningStore.ListCertificatesAsync(tenantId, 500, 0, cancellationToken).ConfigureAwait(false);
var transparencyConfig = await trustSigningStore.GetTransparencyLogConfigAsync(tenantId, cancellationToken).ConfigureAwait(false);
var expiringCertificateCount = certificates.Count(certificate =>
!string.Equals(certificate.Status, "revoked", StringComparison.OrdinalIgnoreCase)
&& certificate.NotAfter <= SnapshotAt.AddDays(10));
var signals = new[]
{
new AdministrationTrustSignalDto("audit-log", "healthy", "Audit log ingestion is current."),
new AdministrationTrustSignalDto("certificate-expiry", "warning", "1 certificate expires within 10 days."),
new AdministrationTrustSignalDto("transparency-log", "healthy", "Rekor witness is reachable."),
new AdministrationTrustSignalDto("trust-scoring", "healthy", "Issuer trust score recalculation completed."),
new AdministrationTrustSignalDto("audit-log", "healthy", "Trust-signing configuration changes are being recorded."),
new AdministrationTrustSignalDto(
"certificate-expiry",
expiringCertificateCount > 0 ? "warning" : "healthy",
expiringCertificateCount > 0
? $"{expiringCertificateCount} certificate{(expiringCertificateCount == 1 ? string.Empty : "s")} expire within 10 days."
: "No certificate expirations are due in the next 10 days."),
new AdministrationTrustSignalDto(
"transparency-log",
transparencyConfig is null ? "warning" : "healthy",
transparencyConfig is null
? "Transparency log is not configured for this tenant."
: $"Transparency log witness points to {transparencyConfig.LogUrl}."),
new AdministrationTrustSignalDto(
"trust-scoring",
issuers.Count == 0 ? "warning" : "healthy",
issuers.Count == 0
? "No trusted issuers are registered yet."
: "Issuer trust inventory is available for scoring and review."),
}.OrderBy(signal => signal.SignalId, StringComparer.Ordinal).ToList();
var aliases = BuildAdministrationAliases(
@@ -558,7 +603,7 @@ public static class PackAdapterEndpoints
]);
return new AdministrationTrustSigningDto(
Inventory: new AdministrationTrustInventoryDto(Keys: 14, Issuers: 7, Certificates: 23),
Inventory: new AdministrationTrustInventoryDto(Keys: keys.Count, Issuers: issuers.Count, Certificates: certificates.Count),
Signals: signals,
LegacyAliases: aliases,
EvidenceConsumerPath: "/evidence-audit/proofs");