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

- 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:
StellaOps Bot
2025-12-06 01:30:08 +02:00
parent 6c1177a6ce
commit 2eaf0f699b
144 changed files with 7578 additions and 2581 deletions

View File

@@ -0,0 +1,158 @@
using System.Text.Json.Serialization;
namespace StellaOps.Concelier.WebService.Options;
/// <summary>
/// Air-gap configuration options for Concelier.
/// Per CONCELIER-WEB-AIRGAP-56-001.
/// </summary>
public sealed class AirGapOptions
{
/// <summary>
/// Enable air-gap mode with bundle-based feed consumption.
/// </summary>
public bool Enabled { get; set; }
/// <summary>
/// Sealed mode configuration (blocks direct internet feeds when enabled).
/// </summary>
public SealedModeOptions SealedMode { get; set; } = new();
/// <summary>
/// Bundle sources configuration.
/// </summary>
public BundleSourcesOptions Sources { get; set; } = new();
/// <summary>
/// Catalog configuration.
/// </summary>
public CatalogOptions Catalog { get; set; } = new();
/// <summary>
/// Sealed mode configuration options.
/// When sealed mode is enabled, direct internet feeds are blocked.
/// </summary>
public sealed class SealedModeOptions
{
/// <summary>
/// Enable sealed mode (block direct internet feeds).
/// </summary>
public bool Enabled { get; set; }
/// <summary>
/// List of sources explicitly allowed even in sealed mode.
/// </summary>
public IList<string> AllowedSources { get; set; } = new List<string>();
/// <summary>
/// List of hosts that are allowed for egress even in sealed mode.
/// Useful for internal mirrors or private registries.
/// </summary>
public IList<string> AllowedHosts { get; set; } = new List<string>();
/// <summary>
/// Warn-only mode: log violations but don't block requests.
/// Useful for testing sealed mode before full enforcement.
/// </summary>
public bool WarnOnly { get; set; }
}
/// <summary>
/// Bundle sources configuration options.
/// </summary>
public sealed class BundleSourcesOptions
{
/// <summary>
/// Root directory for bundle storage.
/// </summary>
public string Root { get; set; } = "bundles";
/// <summary>
/// Automatically register sources from bundle directory on startup.
/// </summary>
public bool AutoDiscovery { get; set; } = true;
/// <summary>
/// File patterns to match for auto-discovery.
/// </summary>
public IList<string> DiscoveryPatterns { get; set; } = new List<string> { "*.bundle.json", "catalog.json" };
/// <summary>
/// Pre-configured bundle sources.
/// </summary>
public IList<BundleSourceConfig> Configured { get; set; } = new List<BundleSourceConfig>();
/// <summary>
/// Computed absolute path to root directory.
/// </summary>
[JsonIgnore]
public string RootAbsolute { get; internal set; } = string.Empty;
}
/// <summary>
/// Configuration for a single bundle source.
/// </summary>
public sealed class BundleSourceConfig
{
/// <summary>
/// Unique identifier for the source.
/// </summary>
public string Id { get; set; } = string.Empty;
/// <summary>
/// Display name for the source.
/// </summary>
public string? DisplayName { get; set; }
/// <summary>
/// Source type (directory, archive, remote).
/// </summary>
public string Type { get; set; } = "directory";
/// <summary>
/// Path or URL to the bundle source.
/// </summary>
public string Location { get; set; } = string.Empty;
/// <summary>
/// Enable this source.
/// </summary>
public bool Enabled { get; set; } = true;
/// <summary>
/// Priority for this source (lower = higher priority).
/// </summary>
public int Priority { get; set; } = 100;
/// <summary>
/// Verification mode for bundles from this source.
/// </summary>
public string VerificationMode { get; set; } = "signature";
}
/// <summary>
/// Catalog configuration options.
/// </summary>
public sealed class CatalogOptions
{
/// <summary>
/// Enable catalog aggregation from all sources.
/// </summary>
public bool Enabled { get; set; } = true;
/// <summary>
/// Cache duration for aggregated catalog in seconds.
/// </summary>
public int CacheDurationSeconds { get; set; } = 300;
/// <summary>
/// Maximum number of items per catalog page.
/// </summary>
public int MaxPageSize { get; set; } = 100;
/// <summary>
/// Include bundle provenance in catalog responses.
/// </summary>
public bool IncludeProvenance { get; set; } = true;
}
}

View File

@@ -27,6 +27,12 @@ public sealed class ConcelierOptions
public StellaOpsCryptoOptions Crypto { get; } = new();
/// <summary>
/// Air-gap mode configuration.
/// Per CONCELIER-WEB-AIRGAP-56-001.
/// </summary>
public AirGapOptions AirGap { get; set; } = new();
public sealed class StorageOptions
{
public string Driver { get; set; } = "mongo";