sprints work

This commit is contained in:
StellaOps Bot
2025-12-24 21:46:08 +02:00
parent 43e2af88f6
commit b9f71fc7e9
161 changed files with 29566 additions and 527 deletions

View File

@@ -0,0 +1,390 @@
// -----------------------------------------------------------------------------
// UnifiedEvidenceContracts.cs
// Sprint: SPRINT_9200_0001_0002_SCANNER_unified_evidence_endpoint
// Description: DTOs for unified evidence endpoint that returns all evidence
// tabs for a finding in one API call.
// -----------------------------------------------------------------------------
namespace StellaOps.Scanner.WebService.Contracts;
/// <summary>
/// Complete evidence package for a finding - all tabs in one response.
/// </summary>
public sealed record UnifiedEvidenceResponseDto
{
/// <summary>Finding this evidence applies to.</summary>
public required string FindingId { get; init; }
/// <summary>CVE identifier.</summary>
public required string CveId { get; init; }
/// <summary>Affected component PURL.</summary>
public required string ComponentPurl { get; init; }
// === Evidence Tabs ===
/// <summary>SBOM evidence - component metadata and linkage.</summary>
public SbomEvidenceDto? Sbom { get; init; }
/// <summary>Reachability evidence - call paths to vulnerable code.</summary>
public ReachabilityEvidenceDto? Reachability { get; init; }
/// <summary>VEX claims from all sources with trust scores.</summary>
public IReadOnlyList<VexClaimDto>? VexClaims { get; init; }
/// <summary>Attestations (in-toto/DSSE) for this artifact.</summary>
public IReadOnlyList<AttestationSummaryDto>? Attestations { get; init; }
/// <summary>Delta comparison since last scan.</summary>
public DeltaEvidenceDto? Deltas { get; init; }
/// <summary>Policy evaluation evidence.</summary>
public PolicyEvidenceDto? Policy { get; init; }
// === Manifest Hashes ===
/// <summary>Content-addressed hashes for determinism verification.</summary>
public required ManifestHashesDto Manifests { get; init; }
// === Verification Status ===
/// <summary>Overall verification status of evidence chain.</summary>
public required VerificationStatusDto Verification { get; init; }
// === Replay Command ===
/// <summary>Copy-ready CLI command to replay this verdict.</summary>
public string? ReplayCommand { get; init; }
/// <summary>Shortened replay command using snapshot ID.</summary>
public string? ShortReplayCommand { get; init; }
/// <summary>URL to download complete evidence bundle.</summary>
public string? EvidenceBundleUrl { get; init; }
// === Metadata ===
/// <summary>When this evidence was assembled.</summary>
public required DateTimeOffset GeneratedAt { get; init; }
/// <summary>Cache key for this response (content-addressed).</summary>
public string? CacheKey { get; init; }
}
/// <summary>
/// SBOM evidence for evidence panel.
/// </summary>
public sealed record SbomEvidenceDto
{
/// <summary>SBOM format (spdx, cyclonedx).</summary>
public required string Format { get; init; }
/// <summary>SBOM version.</summary>
public required string Version { get; init; }
/// <summary>Link to full SBOM document.</summary>
public required string DocumentUri { get; init; }
/// <summary>SBOM content digest.</summary>
public required string Digest { get; init; }
/// <summary>Component entry from SBOM.</summary>
public SbomComponentDto? Component { get; init; }
/// <summary>Dependencies of this component.</summary>
public IReadOnlyList<string>? Dependencies { get; init; }
/// <summary>Dependents (things that depend on this component).</summary>
public IReadOnlyList<string>? Dependents { get; init; }
}
/// <summary>
/// Component information from SBOM.
/// </summary>
public sealed record SbomComponentDto
{
/// <summary>Package URL.</summary>
public required string Purl { get; init; }
/// <summary>Component name.</summary>
public required string Name { get; init; }
/// <summary>Component version.</summary>
public required string Version { get; init; }
/// <summary>Ecosystem (npm, maven, pypi, etc.).</summary>
public string? Ecosystem { get; init; }
/// <summary>License(s).</summary>
public IReadOnlyList<string>? Licenses { get; init; }
/// <summary>CPE identifiers.</summary>
public IReadOnlyList<string>? Cpes { get; init; }
}
/// <summary>
/// Reachability evidence for evidence panel.
/// </summary>
public sealed record ReachabilityEvidenceDto
{
/// <summary>Subgraph ID for detailed view.</summary>
public required string SubgraphId { get; init; }
/// <summary>Reachability status.</summary>
public required string Status { get; init; }
/// <summary>Confidence level (0-1).</summary>
public double Confidence { get; init; }
/// <summary>Analysis method (static, binary, runtime).</summary>
public required string Method { get; init; }
/// <summary>Entry points reaching vulnerable code.</summary>
public IReadOnlyList<EntryPointDto>? EntryPoints { get; init; }
/// <summary>Call chain summary.</summary>
public CallChainSummaryDto? CallChain { get; init; }
/// <summary>Link to full reachability graph.</summary>
public string? GraphUri { get; init; }
}
/// <summary>
/// Entry point information.
/// </summary>
public sealed record EntryPointDto
{
/// <summary>Entry point identifier.</summary>
public required string Id { get; init; }
/// <summary>Entry point type (http, grpc, function, etc.).</summary>
public required string Type { get; init; }
/// <summary>Display name.</summary>
public required string Name { get; init; }
/// <summary>File location if known.</summary>
public string? Location { get; init; }
/// <summary>Distance (hops) to vulnerable code.</summary>
public int? Distance { get; init; }
}
/// <summary>
/// Summary of call chain to vulnerable code.
/// </summary>
public sealed record CallChainSummaryDto
{
/// <summary>Total path length.</summary>
public int PathLength { get; init; }
/// <summary>Number of distinct paths.</summary>
public int PathCount { get; init; }
/// <summary>Key symbols in the chain.</summary>
public IReadOnlyList<string>? KeySymbols { get; init; }
/// <summary>Link to full call graph.</summary>
public string? CallGraphUri { get; init; }
}
/// <summary>
/// VEX claim with trust scoring.
/// </summary>
public sealed record VexClaimDto
{
/// <summary>VEX statement ID.</summary>
public required string StatementId { get; init; }
/// <summary>Source of the VEX statement.</summary>
public required string Source { get; init; }
/// <summary>Status (affected, not_affected, etc.).</summary>
public required string Status { get; init; }
/// <summary>Justification category.</summary>
public string? Justification { get; init; }
/// <summary>Impact statement.</summary>
public string? ImpactStatement { get; init; }
/// <summary>When issued.</summary>
public DateTimeOffset IssuedAt { get; init; }
/// <summary>Trust score (0-1).</summary>
public double TrustScore { get; init; }
/// <summary>Whether this meets policy threshold.</summary>
public bool MeetsPolicyThreshold { get; init; }
/// <summary>Link to full VEX document.</summary>
public string? DocumentUri { get; init; }
}
/// <summary>
/// Attestation summary for evidence panel.
/// </summary>
public sealed record AttestationSummaryDto
{
/// <summary>Attestation ID.</summary>
public required string Id { get; init; }
/// <summary>Predicate type.</summary>
public required string PredicateType { get; init; }
/// <summary>Subject digest.</summary>
public required string SubjectDigest { get; init; }
/// <summary>Signer identity.</summary>
public string? Signer { get; init; }
/// <summary>When signed.</summary>
public DateTimeOffset? SignedAt { get; init; }
/// <summary>Verification status.</summary>
public required string VerificationStatus { get; init; }
/// <summary>Transparency log entry if logged.</summary>
public string? TransparencyLogEntry { get; init; }
/// <summary>Link to full attestation.</summary>
public string? AttestationUri { get; init; }
}
/// <summary>
/// Delta evidence showing what changed.
/// </summary>
public sealed record DeltaEvidenceDto
{
/// <summary>Delta comparison ID.</summary>
public required string DeltaId { get; init; }
/// <summary>Previous scan ID.</summary>
public required string PreviousScanId { get; init; }
/// <summary>Current scan ID.</summary>
public required string CurrentScanId { get; init; }
/// <summary>When comparison was made.</summary>
public DateTimeOffset ComparedAt { get; init; }
/// <summary>Summary of changes.</summary>
public DeltaSummaryDto? Summary { get; init; }
/// <summary>Link to full delta report.</summary>
public string? DeltaReportUri { get; init; }
}
/// <summary>
/// Summary of delta changes.
/// </summary>
public sealed record DeltaSummaryDto
{
/// <summary>New findings.</summary>
public int AddedCount { get; init; }
/// <summary>Removed findings.</summary>
public int RemovedCount { get; init; }
/// <summary>Changed findings.</summary>
public int ChangedCount { get; init; }
/// <summary>Was this finding new in this scan?</summary>
public bool IsNew { get; init; }
/// <summary>Was this finding's status changed?</summary>
public bool StatusChanged { get; init; }
/// <summary>Previous status if changed.</summary>
public string? PreviousStatus { get; init; }
}
/// <summary>
/// Policy evaluation evidence.
/// </summary>
public sealed record PolicyEvidenceDto
{
/// <summary>Policy version used.</summary>
public required string PolicyVersion { get; init; }
/// <summary>Policy digest.</summary>
public required string PolicyDigest { get; init; }
/// <summary>Verdict from policy evaluation.</summary>
public required string Verdict { get; init; }
/// <summary>Rules that fired.</summary>
public IReadOnlyList<PolicyRuleFiredDto>? RulesFired { get; init; }
/// <summary>Counterfactuals - what would change the verdict.</summary>
public IReadOnlyList<string>? Counterfactuals { get; init; }
/// <summary>Link to policy document.</summary>
public string? PolicyDocumentUri { get; init; }
}
/// <summary>
/// Policy rule that fired during evaluation.
/// </summary>
public sealed record PolicyRuleFiredDto
{
/// <summary>Rule ID.</summary>
public required string RuleId { get; init; }
/// <summary>Rule name.</summary>
public required string Name { get; init; }
/// <summary>Effect (allow, deny, warn).</summary>
public required string Effect { get; init; }
/// <summary>Reason the rule fired.</summary>
public string? Reason { get; init; }
}
/// <summary>
/// Content-addressed manifest hashes for determinism verification.
/// </summary>
public sealed record ManifestHashesDto
{
/// <summary>Artifact digest (image or SBOM).</summary>
public required string ArtifactDigest { get; init; }
/// <summary>Run manifest hash.</summary>
public required string ManifestHash { get; init; }
/// <summary>Feed snapshot hash.</summary>
public required string FeedSnapshotHash { get; init; }
/// <summary>Policy hash.</summary>
public required string PolicyHash { get; init; }
/// <summary>Knowledge snapshot ID.</summary>
public string? KnowledgeSnapshotId { get; init; }
/// <summary>Graph revision ID.</summary>
public string? GraphRevisionId { get; init; }
}
/// <summary>
/// Overall verification status.
/// </summary>
public sealed record VerificationStatusDto
{
/// <summary>Overall status (verified, partial, failed, unknown).</summary>
public required string Status { get; init; }
/// <summary>True if all hashes match expected values.</summary>
public bool HashesVerified { get; init; }
/// <summary>True if attestations verify.</summary>
public bool AttestationsVerified { get; init; }
/// <summary>True if evidence is complete.</summary>
public bool EvidenceComplete { get; init; }
/// <summary>Any verification issues.</summary>
public IReadOnlyList<string>? Issues { get; init; }
/// <summary>Last verification timestamp.</summary>
public DateTimeOffset? VerifiedAt { get; init; }
}