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:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
|
||||
Reference in New Issue
Block a user