feat: Implement air-gap functionality with timeline impact and evidence snapshot services
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
Mirror Thin Bundle Sign & Verify / mirror-sign (push) Has been cancelled
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
Mirror Thin Bundle Sign & Verify / mirror-sign (push) Has been cancelled
- Added AirgapTimelineImpact, AirgapTimelineImpactInput, and AirgapTimelineImpactResult records for managing air-gap bundle import impacts. - Introduced EvidenceSnapshotRecord, EvidenceSnapshotLinkInput, and EvidenceSnapshotLinkResult records for linking findings to evidence snapshots. - Created IEvidenceSnapshotRepository interface for managing evidence snapshot records. - Developed StalenessValidationService to validate staleness and enforce freshness thresholds. - Implemented AirgapTimelineService for emitting timeline events related to bundle imports. - Added EvidenceSnapshotService for linking findings to evidence snapshots and verifying their validity. - Introduced AirGapOptions for configuring air-gap staleness enforcement and thresholds. - Added minimal jsPDF stub for offline/testing builds in the web application. - Created TypeScript definitions for jsPDF to enhance type safety in the web application.
This commit is contained in:
@@ -15,6 +15,8 @@ internal static class LedgerTimeline
|
||||
private static readonly EventId ProjectionUpdated = new(6201, "ledger.projection.updated");
|
||||
private static readonly EventId OrchestratorExport = new(6301, "ledger.export.recorded");
|
||||
private static readonly EventId AirgapImport = new(6401, "ledger.airgap.imported");
|
||||
private static readonly EventId EvidenceSnapshotLinkedEvent = new(6501, "ledger.evidence.snapshot_linked");
|
||||
private static readonly EventId AirgapTimelineImpactEvent = new(6601, "ledger.airgap.timeline_impact");
|
||||
|
||||
public static void EmitLedgerAppended(ILogger logger, LedgerEventRecord record, string? evidenceBundleRef = null)
|
||||
{
|
||||
@@ -99,4 +101,47 @@ internal static class LedgerTimeline
|
||||
merkleRoot,
|
||||
ledgerEventId?.ToString() ?? string.Empty);
|
||||
}
|
||||
|
||||
public static void EmitEvidenceSnapshotLinked(ILogger logger, string tenantId, string findingId, string bundleUri, string dsseDigest)
|
||||
{
|
||||
if (logger is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
logger.LogInformation(
|
||||
EvidenceSnapshotLinkedEvent,
|
||||
"timeline ledger.evidence.snapshot_linked tenant={Tenant} finding={FindingId} bundle_uri={BundleUri} dsse_digest={DsseDigest}",
|
||||
tenantId,
|
||||
findingId,
|
||||
bundleUri,
|
||||
dsseDigest);
|
||||
}
|
||||
|
||||
public static void EmitAirgapTimelineImpact(
|
||||
ILogger logger,
|
||||
string tenantId,
|
||||
string bundleId,
|
||||
int newFindings,
|
||||
int resolvedFindings,
|
||||
int criticalDelta,
|
||||
DateTimeOffset timeAnchor,
|
||||
bool sealedMode)
|
||||
{
|
||||
if (logger is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
logger.LogInformation(
|
||||
AirgapTimelineImpactEvent,
|
||||
"timeline ledger.airgap.timeline_impact tenant={Tenant} bundle={BundleId} new_findings={NewFindings} resolved_findings={ResolvedFindings} critical_delta={CriticalDelta} time_anchor={TimeAnchor} sealed_mode={SealedMode}",
|
||||
tenantId,
|
||||
bundleId,
|
||||
newFindings,
|
||||
resolvedFindings,
|
||||
criticalDelta,
|
||||
timeAnchor.ToString("O"),
|
||||
sealedMode);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user