Files
git.stella-ops.org/src/__Libraries/StellaOps.Evidence.Pack/Models/SignedEvidencePack.cs

147 lines
4.5 KiB
C#

// <copyright file="SignedEvidencePack.cs" company="StellaOps">
// Copyright (c) StellaOps. Licensed under the BUSL-1.1.
// </copyright>
using System.Collections.Immutable;
namespace StellaOps.Evidence.Pack.Models;
/// <summary>
/// A signed evidence pack with DSSE envelope.
/// Sprint: SPRINT_20260109_011_005 Task: EVPK-001
/// </summary>
public sealed record SignedEvidencePack
{
/// <summary>Gets the evidence pack.</summary>
public required EvidencePack Pack { get; init; }
/// <summary>Gets the DSSE envelope containing the signature.</summary>
public required DsseEnvelope Envelope { get; init; }
/// <summary>Gets when the pack was signed.</summary>
public required DateTimeOffset SignedAt { get; init; }
}
/// <summary>
/// DSSE (Dead Simple Signing Envelope) for evidence pack signatures.
/// See: https://github.com/secure-systems-lab/dsse
/// </summary>
public sealed record DsseEnvelope
{
/// <summary>Gets the payload type URI.</summary>
public required string PayloadType { get; init; }
/// <summary>Gets the base64-encoded payload.</summary>
public required string Payload { get; init; }
/// <summary>Gets the computed payload digest.</summary>
public required string PayloadDigest { get; init; }
/// <summary>Gets the signatures.</summary>
public required ImmutableArray<DsseSignature> Signatures { get; init; }
}
/// <summary>
/// A signature within a DSSE envelope.
/// </summary>
public sealed record DsseSignature
{
/// <summary>Gets the key identifier.</summary>
public required string KeyId { get; init; }
/// <summary>Gets the base64-encoded signature.</summary>
public required string Sig { get; init; }
}
/// <summary>
/// Result of verifying an evidence pack.
/// </summary>
public sealed record EvidencePackVerificationResult
{
/// <summary>Gets whether the pack is valid.</summary>
public required bool Valid { get; init; }
/// <summary>Gets the pack content digest.</summary>
public required string PackDigest { get; init; }
/// <summary>Gets the signing key identifier.</summary>
public required string SignatureKeyId { get; init; }
/// <summary>Gets any verification issues.</summary>
public ImmutableArray<string> Issues { get; init; } = ImmutableArray<string>.Empty;
/// <summary>Gets individual evidence resolution results.</summary>
public ImmutableArray<EvidenceResolutionResult> EvidenceResolutions { get; init; } = ImmutableArray<EvidenceResolutionResult>.Empty;
}
/// <summary>
/// Result of resolving a single evidence item.
/// </summary>
public sealed record EvidenceResolutionResult
{
/// <summary>Gets the evidence identifier.</summary>
public required string EvidenceId { get; init; }
/// <summary>Gets the evidence URI.</summary>
public required string Uri { get; init; }
/// <summary>Gets whether the evidence was resolved.</summary>
public required bool Resolved { get; init; }
/// <summary>Gets whether the digest matches.</summary>
public required bool DigestMatches { get; init; }
/// <summary>Gets any resolution error.</summary>
public string? Error { get; init; }
}
/// <summary>
/// Export format options for evidence packs.
/// </summary>
public enum EvidencePackExportFormat
{
/// <summary>Raw JSON format.</summary>
Json,
/// <summary>Signed JSON with DSSE envelope.</summary>
SignedJson,
/// <summary>Human-readable Markdown.</summary>
Markdown,
/// <summary>PDF report.</summary>
Pdf,
/// <summary>Styled HTML report.</summary>
Html,
// Sprint: SPRINT_20260112_005_BE_evidence_card_api (EVPCARD-BE-001)
/// <summary>Single-file evidence card with SBOM excerpt, DSSE envelope, and Rekor receipt.</summary>
EvidenceCard,
/// <summary>Compact evidence card without full SBOM.</summary>
EvidenceCardCompact
}
/// <summary>
/// Result of exporting an evidence pack.
/// </summary>
public sealed record EvidencePackExport
{
/// <summary>Gets the pack identifier.</summary>
public required string PackId { get; init; }
/// <summary>Gets the export format.</summary>
public required EvidencePackExportFormat Format { get; init; }
/// <summary>Gets the content bytes.</summary>
public required byte[] Content { get; init; }
/// <summary>Gets the content type.</summary>
public required string ContentType { get; init; }
/// <summary>Gets the suggested filename.</summary>
public required string FileName { get; init; }
}