update evidence bundle to include new evidence types and implement ProofSpine integration
Some checks failed
Lighthouse CI / Lighthouse Audit (push) Has been cancelled
Lighthouse CI / Axe Accessibility Audit (push) Has been cancelled
Manifest Integrity / Validate Pack Fixtures (push) Has been cancelled
Manifest Integrity / Validate Schema Integrity (push) Has been cancelled
Manifest Integrity / Validate Contract Documents (push) Has been cancelled
Manifest Integrity / Audit SHA256SUMS Files (push) Has been cancelled
Manifest Integrity / Verify Merkle Roots (push) Has been cancelled
api-governance / spectral-lint (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
sm-remote-ci / build-and-test (push) Has been cancelled
Notify Smoke Test / Notification Smoke Test (push) Has been cancelled
oas-ci / oas-validate (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
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Notify Smoke Test / Notify Unit Tests (push) Has been cancelled
Notify Smoke Test / Notifier Service Tests (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Some checks failed
Lighthouse CI / Lighthouse Audit (push) Has been cancelled
Lighthouse CI / Axe Accessibility Audit (push) Has been cancelled
Manifest Integrity / Validate Pack Fixtures (push) Has been cancelled
Manifest Integrity / Validate Schema Integrity (push) Has been cancelled
Manifest Integrity / Validate Contract Documents (push) Has been cancelled
Manifest Integrity / Audit SHA256SUMS Files (push) Has been cancelled
Manifest Integrity / Verify Merkle Roots (push) Has been cancelled
api-governance / spectral-lint (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
sm-remote-ci / build-and-test (push) Has been cancelled
Notify Smoke Test / Notification Smoke Test (push) Has been cancelled
oas-ci / oas-validate (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
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Notify Smoke Test / Notify Unit Tests (push) Has been cancelled
Notify Smoke Test / Notifier Service Tests (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
namespace StellaOps.Evidence.Bundle;
|
||||
|
||||
/// <summary>Call stack snippet evidence.</summary>
|
||||
public sealed class CallStackEvidence
|
||||
{
|
||||
public required EvidenceStatus Status { get; init; }
|
||||
public string? Hash { get; init; }
|
||||
public IReadOnlyList<StackFrame>? Frames { get; init; }
|
||||
public int? SinkFrameIndex { get; init; }
|
||||
public int? SourceFrameIndex { get; init; }
|
||||
public string? UnavailableReason { get; init; }
|
||||
}
|
||||
|
||||
public sealed class StackFrame
|
||||
{
|
||||
public required string FunctionName { get; init; }
|
||||
public required string FilePath { get; init; }
|
||||
public required int Line { get; init; }
|
||||
public int? Column { get; init; }
|
||||
public string? SourceSnippet { get; init; }
|
||||
public bool IsSink { get; init; }
|
||||
public bool IsSource { get; init; }
|
||||
}
|
||||
26
src/__Libraries/StellaOps.Evidence.Bundle/DiffEvidence.cs
Normal file
26
src/__Libraries/StellaOps.Evidence.Bundle/DiffEvidence.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
namespace StellaOps.Evidence.Bundle;
|
||||
|
||||
/// <summary>SBOM/VEX diff evidence.</summary>
|
||||
public sealed class DiffEvidence
|
||||
{
|
||||
public required EvidenceStatus Status { get; init; }
|
||||
public string? Hash { get; init; }
|
||||
public DiffType DiffType { get; init; }
|
||||
public IReadOnlyList<DiffEntry>? Entries { get; init; }
|
||||
public string? PreviousScanId { get; init; }
|
||||
public DateTimeOffset? PreviousScanTime { get; init; }
|
||||
public string? UnavailableReason { get; init; }
|
||||
}
|
||||
|
||||
public enum DiffType { Sbom, Vex, Combined }
|
||||
|
||||
public sealed class DiffEntry
|
||||
{
|
||||
public required DiffOperation Operation { get; init; }
|
||||
public required string Path { get; init; }
|
||||
public string? OldValue { get; init; }
|
||||
public string? NewValue { get; init; }
|
||||
public string? ComponentPurl { get; init; }
|
||||
}
|
||||
|
||||
public enum DiffOperation { Added, Removed, Modified }
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace StellaOps.Evidence.Bundle;
|
||||
|
||||
/// <summary>A complete evidence bundle for a single finding/alert. Contains all evidence required for triage decision.</summary>
|
||||
/// <summary>A complete evidence bundle for a single finding/alert.</summary>
|
||||
public sealed class EvidenceBundle
|
||||
{
|
||||
public string BundleId { get; init; } = Guid.NewGuid().ToString("N");
|
||||
@@ -16,7 +16,6 @@ public sealed class EvidenceBundle
|
||||
public required EvidenceHashSet Hashes { get; init; }
|
||||
public required DateTimeOffset CreatedAt { get; init; }
|
||||
|
||||
/// <summary>Compute evidence completeness score (0-4 based on core evidence types).</summary>
|
||||
public int ComputeCompletenessScore()
|
||||
{
|
||||
var score = 0;
|
||||
@@ -27,7 +26,6 @@ public sealed class EvidenceBundle
|
||||
return score;
|
||||
}
|
||||
|
||||
/// <summary>Create status summary from evidence.</summary>
|
||||
public EvidenceStatusSummary CreateStatusSummary() => new()
|
||||
{
|
||||
Reachability = Reachability?.Status ?? EvidenceStatus.Unavailable,
|
||||
@@ -38,7 +36,6 @@ public sealed class EvidenceBundle
|
||||
GraphRevision = GraphRevision?.Status ?? EvidenceStatus.Unavailable
|
||||
};
|
||||
|
||||
/// <summary>Create DSSE predicate for signing.</summary>
|
||||
public EvidenceBundlePredicate ToSigningPredicate() => new()
|
||||
{
|
||||
BundleId = BundleId,
|
||||
|
||||
@@ -13,28 +13,22 @@ public sealed class EvidenceBundleBuilder
|
||||
private DiffEvidence? _diff;
|
||||
private GraphRevisionEvidence? _graphRevision;
|
||||
|
||||
public EvidenceBundleBuilder(TimeProvider timeProvider)
|
||||
{
|
||||
_timeProvider = timeProvider ?? throw new ArgumentNullException(nameof(timeProvider));
|
||||
}
|
||||
|
||||
public EvidenceBundleBuilder(TimeProvider timeProvider) => _timeProvider = timeProvider ?? throw new ArgumentNullException(nameof(timeProvider));
|
||||
public EvidenceBundleBuilder() : this(TimeProvider.System) { }
|
||||
|
||||
public EvidenceBundleBuilder WithAlertId(string alertId) { _alertId = alertId; return this; }
|
||||
public EvidenceBundleBuilder WithArtifactId(string artifactId) { _artifactId = artifactId; return this; }
|
||||
public EvidenceBundleBuilder WithReachability(ReachabilityEvidence evidence) { _reachability = evidence; return this; }
|
||||
public EvidenceBundleBuilder WithCallStack(CallStackEvidence evidence) { _callStack = evidence; return this; }
|
||||
public EvidenceBundleBuilder WithProvenance(ProvenanceEvidence evidence) { _provenance = evidence; return this; }
|
||||
public EvidenceBundleBuilder WithVexStatus(VexStatusEvidence evidence) { _vexStatus = evidence; return this; }
|
||||
public EvidenceBundleBuilder WithDiff(DiffEvidence evidence) { _diff = evidence; return this; }
|
||||
public EvidenceBundleBuilder WithGraphRevision(GraphRevisionEvidence evidence) { _graphRevision = evidence; return this; }
|
||||
public EvidenceBundleBuilder WithReachability(ReachabilityEvidence e) { _reachability = e; return this; }
|
||||
public EvidenceBundleBuilder WithCallStack(CallStackEvidence e) { _callStack = e; return this; }
|
||||
public EvidenceBundleBuilder WithProvenance(ProvenanceEvidence e) { _provenance = e; return this; }
|
||||
public EvidenceBundleBuilder WithVexStatus(VexStatusEvidence e) { _vexStatus = e; return this; }
|
||||
public EvidenceBundleBuilder WithDiff(DiffEvidence e) { _diff = e; return this; }
|
||||
public EvidenceBundleBuilder WithGraphRevision(GraphRevisionEvidence e) { _graphRevision = e; return this; }
|
||||
|
||||
public EvidenceBundle Build()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(_alertId))
|
||||
throw new InvalidOperationException("AlertId is required");
|
||||
if (string.IsNullOrWhiteSpace(_artifactId))
|
||||
throw new InvalidOperationException("ArtifactId is required");
|
||||
if (string.IsNullOrWhiteSpace(_alertId)) throw new InvalidOperationException("AlertId is required");
|
||||
if (string.IsNullOrWhiteSpace(_artifactId)) throw new InvalidOperationException("ArtifactId is required");
|
||||
|
||||
var hashes = new Dictionary<string, string>();
|
||||
if (_reachability?.Hash is not null) hashes["reachability"] = _reachability.Hash;
|
||||
|
||||
16
src/__Libraries/StellaOps.Evidence.Bundle/EvidenceStatus.cs
Normal file
16
src/__Libraries/StellaOps.Evidence.Bundle/EvidenceStatus.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
namespace StellaOps.Evidence.Bundle;
|
||||
|
||||
/// <summary>Status of an evidence artifact.</summary>
|
||||
public enum EvidenceStatus
|
||||
{
|
||||
/// <summary>Evidence is available and complete.</summary>
|
||||
Available,
|
||||
/// <summary>Evidence is currently being loaded/computed.</summary>
|
||||
Loading,
|
||||
/// <summary>Evidence is not available (missing inputs).</summary>
|
||||
Unavailable,
|
||||
/// <summary>Error occurred while fetching evidence.</summary>
|
||||
Error,
|
||||
/// <summary>Evidence pending enrichment (offline mode).</summary>
|
||||
PendingEnrichment
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace StellaOps.Evidence.Bundle;
|
||||
|
||||
/// <summary>Graph revision and verdict receipt evidence.</summary>
|
||||
public sealed class GraphRevisionEvidence
|
||||
{
|
||||
public required EvidenceStatus Status { get; init; }
|
||||
public string? Hash { get; init; }
|
||||
public required string GraphRevisionId { get; init; }
|
||||
public string? VerdictReceipt { get; init; }
|
||||
public DateTimeOffset? GraphComputedAt { get; init; }
|
||||
public int? TotalNodes { get; init; }
|
||||
public int? TotalEdges { get; init; }
|
||||
public string? UnavailableReason { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
namespace StellaOps.Evidence.Bundle;
|
||||
|
||||
/// <summary>Provenance attestation evidence.</summary>
|
||||
public sealed class ProvenanceEvidence
|
||||
{
|
||||
public required EvidenceStatus Status { get; init; }
|
||||
public string? Hash { get; init; }
|
||||
public DsseEnvelope? DsseEnvelope { get; init; }
|
||||
public BuildAncestry? Ancestry { get; init; }
|
||||
public RekorReference? RekorEntry { get; init; }
|
||||
public string? VerificationStatus { get; init; }
|
||||
public string? UnavailableReason { get; init; }
|
||||
}
|
||||
|
||||
public sealed class DsseEnvelope
|
||||
{
|
||||
public required string PayloadType { get; init; }
|
||||
public required string Payload { get; init; }
|
||||
public required IReadOnlyList<DsseSignature> Signatures { get; init; }
|
||||
}
|
||||
|
||||
public sealed class DsseSignature
|
||||
{
|
||||
public required string KeyId { get; init; }
|
||||
public required string Sig { get; init; }
|
||||
}
|
||||
|
||||
public sealed class BuildAncestry
|
||||
{
|
||||
public string? ImageDigest { get; init; }
|
||||
public string? LayerDigest { get; init; }
|
||||
public string? ArtifactDigest { get; init; }
|
||||
public string? CommitHash { get; init; }
|
||||
public string? BuildId { get; init; }
|
||||
public DateTimeOffset? BuildTime { get; init; }
|
||||
}
|
||||
|
||||
public sealed class RekorReference
|
||||
{
|
||||
public required string LogId { get; init; }
|
||||
public required long LogIndex { get; init; }
|
||||
public string? Uuid { get; init; }
|
||||
public DateTimeOffset? IntegratedTime { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
namespace StellaOps.Evidence.Bundle;
|
||||
|
||||
/// <summary>Reachability proof evidence.</summary>
|
||||
public sealed class ReachabilityEvidence
|
||||
{
|
||||
public required EvidenceStatus Status { get; init; }
|
||||
public string? Hash { get; init; }
|
||||
public ReachabilityProofType ProofType { get; init; }
|
||||
public IReadOnlyList<FunctionPathNode>? FunctionPath { get; init; }
|
||||
public IReadOnlyList<PackageImportNode>? ImportChain { get; init; }
|
||||
public string? LatticeState { get; init; }
|
||||
public int? ConfidenceTier { get; init; }
|
||||
public string? UnavailableReason { get; init; }
|
||||
}
|
||||
|
||||
public enum ReachabilityProofType { FunctionLevel, PackageLevel, ImportChain, Heuristic, Unknown }
|
||||
|
||||
public sealed class FunctionPathNode
|
||||
{
|
||||
public required string FunctionName { get; init; }
|
||||
public required string FilePath { get; init; }
|
||||
public required int Line { get; init; }
|
||||
public int? Column { get; init; }
|
||||
public string? ModuleName { get; init; }
|
||||
}
|
||||
|
||||
public sealed class PackageImportNode
|
||||
{
|
||||
public required string PackageName { get; init; }
|
||||
public string? Version { get; init; }
|
||||
public string? ImportedBy { get; init; }
|
||||
public string? ImportPath { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" ?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<RootNamespace>StellaOps.Evidence.Bundle</RootNamespace>
|
||||
<Description>Evidence bundle envelope with cryptographic signatures for offline verification</Description>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.0-preview.1.25080.5" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,21 @@
|
||||
namespace StellaOps.Evidence.Bundle;
|
||||
|
||||
/// <summary>VEX/CSAF status evidence.</summary>
|
||||
public sealed class VexStatusEvidence
|
||||
{
|
||||
public required EvidenceStatus Status { get; init; }
|
||||
public string? Hash { get; init; }
|
||||
public VexStatement? Current { get; init; }
|
||||
public IReadOnlyList<VexStatement>? History { get; init; }
|
||||
public string? UnavailableReason { get; init; }
|
||||
}
|
||||
|
||||
public sealed class VexStatement
|
||||
{
|
||||
public required string VexStatus { get; init; }
|
||||
public string? Justification { get; init; }
|
||||
public string? ImpactStatement { get; init; }
|
||||
public string? ActionStatement { get; init; }
|
||||
public DateTimeOffset? Timestamp { get; init; }
|
||||
public string? Source { get; init; }
|
||||
}
|
||||
Reference in New Issue
Block a user