- Implemented Attestation Chain API client with methods for verifying, fetching, and managing attestation chains. - Created models for Attestation Chain, including DSSE envelope structures and verification results. - Developed Triage Evidence API client for fetching finding evidence, including methods for evidence retrieval by CVE and component. - Added models for Triage Evidence, encapsulating evidence responses, entry points, boundary proofs, and VEX evidence. - Introduced mock implementations for both API clients to facilitate testing and development.
92 lines
2.5 KiB
C#
92 lines
2.5 KiB
C#
using System.ComponentModel.DataAnnotations;
|
|
using System.ComponentModel.DataAnnotations.Schema;
|
|
|
|
namespace StellaOps.Scanner.Triage.Entities;
|
|
|
|
/// <summary>
|
|
/// Effective VEX status for a finding after merging multiple VEX sources.
|
|
/// Preserves provenance pointers for auditability.
|
|
/// </summary>
|
|
[Table("triage_effective_vex")]
|
|
public sealed class TriageEffectiveVex
|
|
{
|
|
/// <summary>
|
|
/// Unique identifier.
|
|
/// </summary>
|
|
[Key]
|
|
[Column("id")]
|
|
public Guid Id { get; init; } = Guid.NewGuid();
|
|
|
|
/// <summary>
|
|
/// The finding this VEX status applies to.
|
|
/// </summary>
|
|
[Column("finding_id")]
|
|
public Guid FindingId { get; init; }
|
|
|
|
/// <summary>
|
|
/// The effective VEX status after merging.
|
|
/// </summary>
|
|
[Column("status")]
|
|
public TriageVexStatus Status { get; init; }
|
|
|
|
/// <summary>
|
|
/// Source domain that provided this VEX (e.g., "excititor").
|
|
/// </summary>
|
|
[Required]
|
|
[Column("source_domain")]
|
|
public required string SourceDomain { get; init; }
|
|
|
|
/// <summary>
|
|
/// Stable reference string to the source document.
|
|
/// </summary>
|
|
[Required]
|
|
[Column("source_ref")]
|
|
public required string SourceRef { get; init; }
|
|
|
|
/// <summary>
|
|
/// Array of pruned VEX sources with reasons (for merge transparency).
|
|
/// </summary>
|
|
[Column("pruned_sources", TypeName = "jsonb")]
|
|
public string? PrunedSourcesJson { get; init; }
|
|
|
|
/// <summary>
|
|
/// Hash of the DSSE envelope if signed.
|
|
/// </summary>
|
|
[Column("dsse_envelope_hash")]
|
|
public string? DsseEnvelopeHash { get; init; }
|
|
|
|
/// <summary>
|
|
/// Reference to Rekor/ledger entry for signature verification.
|
|
/// </summary>
|
|
[Column("signature_ref")]
|
|
public string? SignatureRef { get; init; }
|
|
|
|
/// <summary>
|
|
/// Issuer of the VEX document.
|
|
/// </summary>
|
|
[Column("issuer")]
|
|
public string? Issuer { get; init; }
|
|
|
|
/// <summary>
|
|
/// When this VEX status became valid.
|
|
/// </summary>
|
|
[Column("valid_from")]
|
|
public DateTimeOffset ValidFrom { get; init; } = DateTimeOffset.UtcNow;
|
|
|
|
/// <summary>
|
|
/// When this VEX status expires (null = indefinite).
|
|
/// </summary>
|
|
[Column("valid_to")]
|
|
public DateTimeOffset? ValidTo { get; init; }
|
|
|
|
/// <summary>
|
|
/// When this record was collected.
|
|
/// </summary>
|
|
[Column("collected_at")]
|
|
public DateTimeOffset CollectedAt { get; init; } = DateTimeOffset.UtcNow;
|
|
|
|
// Navigation property
|
|
[ForeignKey(nameof(FindingId))]
|
|
public TriageFinding? Finding { get; init; }
|
|
}
|