up
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
Policy Lint & Smoke / policy-lint (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
Policy Lint & Smoke / policy-lint (push) Has been cancelled
This commit is contained in:
@@ -35,3 +35,60 @@ internal sealed record TenantProfile
|
||||
[JsonPropertyName("lastUpdated")]
|
||||
public DateTimeOffset? LastUpdated { get; init; }
|
||||
}
|
||||
|
||||
// CLI-TEN-49-001: Token minting and delegation models
|
||||
|
||||
/// <summary>
|
||||
/// Request to mint a service account token.
|
||||
/// </summary>
|
||||
internal sealed record TokenMintRequest(
|
||||
[property: JsonPropertyName("serviceAccountId")] string ServiceAccountId,
|
||||
[property: JsonPropertyName("scopes")] IReadOnlyList<string> Scopes,
|
||||
[property: JsonPropertyName("expiresInSeconds")] int? ExpiresInSeconds = null,
|
||||
[property: JsonPropertyName("tenant")] string? Tenant = null,
|
||||
[property: JsonPropertyName("reason")] string? Reason = null);
|
||||
|
||||
/// <summary>
|
||||
/// Response from token minting.
|
||||
/// </summary>
|
||||
internal sealed record TokenMintResponse(
|
||||
[property: JsonPropertyName("accessToken")] string AccessToken,
|
||||
[property: JsonPropertyName("tokenType")] string TokenType,
|
||||
[property: JsonPropertyName("expiresAt")] DateTimeOffset ExpiresAt,
|
||||
[property: JsonPropertyName("scopes")] IReadOnlyList<string> Scopes,
|
||||
[property: JsonPropertyName("tokenId")] string? TokenId = null);
|
||||
|
||||
/// <summary>
|
||||
/// Request to delegate a token to another principal.
|
||||
/// </summary>
|
||||
internal sealed record TokenDelegateRequest(
|
||||
[property: JsonPropertyName("delegateTo")] string DelegateTo,
|
||||
[property: JsonPropertyName("scopes")] IReadOnlyList<string> Scopes,
|
||||
[property: JsonPropertyName("expiresInSeconds")] int? ExpiresInSeconds = null,
|
||||
[property: JsonPropertyName("tenant")] string? Tenant = null,
|
||||
[property: JsonPropertyName("reason")] string? Reason = null);
|
||||
|
||||
/// <summary>
|
||||
/// Response from token delegation.
|
||||
/// </summary>
|
||||
internal sealed record TokenDelegateResponse(
|
||||
[property: JsonPropertyName("accessToken")] string AccessToken,
|
||||
[property: JsonPropertyName("tokenType")] string TokenType,
|
||||
[property: JsonPropertyName("expiresAt")] DateTimeOffset ExpiresAt,
|
||||
[property: JsonPropertyName("delegationId")] string DelegationId,
|
||||
[property: JsonPropertyName("originalSubject")] string OriginalSubject,
|
||||
[property: JsonPropertyName("delegatedSubject")] string DelegatedSubject,
|
||||
[property: JsonPropertyName("scopes")] IReadOnlyList<string> Scopes);
|
||||
|
||||
/// <summary>
|
||||
/// Token introspection response for impersonation banner.
|
||||
/// </summary>
|
||||
internal sealed record TokenIntrospectionResponse(
|
||||
[property: JsonPropertyName("active")] bool Active,
|
||||
[property: JsonPropertyName("sub")] string? Subject = null,
|
||||
[property: JsonPropertyName("clientId")] string? ClientId = null,
|
||||
[property: JsonPropertyName("scope")] string? Scope = null,
|
||||
[property: JsonPropertyName("exp")] long? ExpiresAt = null,
|
||||
[property: JsonPropertyName("iat")] long? IssuedAt = null,
|
||||
[property: JsonPropertyName("delegatedBy")] string? DelegatedBy = null,
|
||||
[property: JsonPropertyName("delegationReason")] string? DelegationReason = null);
|
||||
|
||||
258
src/Cli/StellaOps.Cli/Services/Models/VexModels.cs
Normal file
258
src/Cli/StellaOps.Cli/Services/Models/VexModels.cs
Normal file
@@ -0,0 +1,258 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace StellaOps.Cli.Services.Models;
|
||||
|
||||
// CLI-VEX-30-001: VEX consensus models for CLI
|
||||
|
||||
/// <summary>
|
||||
/// VEX consensus list request parameters.
|
||||
/// </summary>
|
||||
internal sealed record VexConsensusListRequest(
|
||||
[property: JsonPropertyName("vulnerabilityId")] string? VulnerabilityId = null,
|
||||
[property: JsonPropertyName("productKey")] string? ProductKey = null,
|
||||
[property: JsonPropertyName("purl")] string? Purl = null,
|
||||
[property: JsonPropertyName("status")] string? Status = null,
|
||||
[property: JsonPropertyName("policyVersion")] string? PolicyVersion = null,
|
||||
[property: JsonPropertyName("limit")] int? Limit = null,
|
||||
[property: JsonPropertyName("offset")] int? Offset = null);
|
||||
|
||||
/// <summary>
|
||||
/// Paginated VEX consensus list response.
|
||||
/// </summary>
|
||||
internal sealed record VexConsensusListResponse(
|
||||
[property: JsonPropertyName("items")] IReadOnlyList<VexConsensusItem> Items,
|
||||
[property: JsonPropertyName("total")] int Total,
|
||||
[property: JsonPropertyName("limit")] int Limit,
|
||||
[property: JsonPropertyName("offset")] int Offset,
|
||||
[property: JsonPropertyName("hasMore")] bool HasMore);
|
||||
|
||||
/// <summary>
|
||||
/// VEX consensus item from the API.
|
||||
/// </summary>
|
||||
internal sealed record VexConsensusItem(
|
||||
[property: JsonPropertyName("vulnerabilityId")] string VulnerabilityId,
|
||||
[property: JsonPropertyName("product")] VexProductInfo Product,
|
||||
[property: JsonPropertyName("status")] string Status,
|
||||
[property: JsonPropertyName("calculatedAt")] DateTimeOffset CalculatedAt,
|
||||
[property: JsonPropertyName("sources")] IReadOnlyList<VexConsensusSourceInfo> Sources,
|
||||
[property: JsonPropertyName("conflicts")] IReadOnlyList<VexConsensusConflictInfo>? Conflicts = null,
|
||||
[property: JsonPropertyName("policyVersion")] string? PolicyVersion = null,
|
||||
[property: JsonPropertyName("policyDigest")] string? PolicyDigest = null,
|
||||
[property: JsonPropertyName("summary")] string? Summary = null);
|
||||
|
||||
/// <summary>
|
||||
/// VEX product information.
|
||||
/// </summary>
|
||||
internal sealed record VexProductInfo(
|
||||
[property: JsonPropertyName("key")] string Key,
|
||||
[property: JsonPropertyName("name")] string? Name = null,
|
||||
[property: JsonPropertyName("version")] string? Version = null,
|
||||
[property: JsonPropertyName("purl")] string? Purl = null,
|
||||
[property: JsonPropertyName("cpe")] string? Cpe = null);
|
||||
|
||||
/// <summary>
|
||||
/// VEX consensus source (accepted claim).
|
||||
/// </summary>
|
||||
internal sealed record VexConsensusSourceInfo(
|
||||
[property: JsonPropertyName("providerId")] string ProviderId,
|
||||
[property: JsonPropertyName("status")] string Status,
|
||||
[property: JsonPropertyName("documentDigest")] string? DocumentDigest = null,
|
||||
[property: JsonPropertyName("weight")] double Weight = 1.0,
|
||||
[property: JsonPropertyName("justification")] string? Justification = null,
|
||||
[property: JsonPropertyName("detail")] string? Detail = null,
|
||||
[property: JsonPropertyName("confidence")] VexConfidenceInfo? Confidence = null);
|
||||
|
||||
/// <summary>
|
||||
/// VEX consensus conflict (rejected claim).
|
||||
/// </summary>
|
||||
internal sealed record VexConsensusConflictInfo(
|
||||
[property: JsonPropertyName("providerId")] string ProviderId,
|
||||
[property: JsonPropertyName("status")] string Status,
|
||||
[property: JsonPropertyName("documentDigest")] string? DocumentDigest = null,
|
||||
[property: JsonPropertyName("justification")] string? Justification = null,
|
||||
[property: JsonPropertyName("detail")] string? Detail = null,
|
||||
[property: JsonPropertyName("reason")] string? Reason = null);
|
||||
|
||||
/// <summary>
|
||||
/// VEX confidence information.
|
||||
/// </summary>
|
||||
internal sealed record VexConfidenceInfo(
|
||||
[property: JsonPropertyName("level")] string? Level = null,
|
||||
[property: JsonPropertyName("score")] double? Score = null,
|
||||
[property: JsonPropertyName("method")] string? Method = null);
|
||||
|
||||
// CLI-VEX-30-002: VEX consensus detail models
|
||||
|
||||
/// <summary>
|
||||
/// Detailed VEX consensus response including quorum, evidence, rationale, and signature status.
|
||||
/// </summary>
|
||||
internal sealed record VexConsensusDetailResponse(
|
||||
[property: JsonPropertyName("vulnerabilityId")] string VulnerabilityId,
|
||||
[property: JsonPropertyName("product")] VexProductInfo Product,
|
||||
[property: JsonPropertyName("status")] string Status,
|
||||
[property: JsonPropertyName("calculatedAt")] DateTimeOffset CalculatedAt,
|
||||
[property: JsonPropertyName("sources")] IReadOnlyList<VexConsensusSourceInfo> Sources,
|
||||
[property: JsonPropertyName("conflicts")] IReadOnlyList<VexConsensusConflictInfo>? Conflicts = null,
|
||||
[property: JsonPropertyName("policyVersion")] string? PolicyVersion = null,
|
||||
[property: JsonPropertyName("policyDigest")] string? PolicyDigest = null,
|
||||
[property: JsonPropertyName("summary")] string? Summary = null,
|
||||
[property: JsonPropertyName("quorum")] VexQuorumInfo? Quorum = null,
|
||||
[property: JsonPropertyName("rationale")] VexRationaleInfo? Rationale = null,
|
||||
[property: JsonPropertyName("signature")] VexSignatureInfo? Signature = null,
|
||||
[property: JsonPropertyName("evidence")] IReadOnlyList<VexEvidenceInfo>? Evidence = null);
|
||||
|
||||
/// <summary>
|
||||
/// VEX quorum information showing how consensus was reached.
|
||||
/// </summary>
|
||||
internal sealed record VexQuorumInfo(
|
||||
[property: JsonPropertyName("required")] int Required,
|
||||
[property: JsonPropertyName("achieved")] int Achieved,
|
||||
[property: JsonPropertyName("threshold")] double Threshold,
|
||||
[property: JsonPropertyName("totalWeight")] double TotalWeight,
|
||||
[property: JsonPropertyName("weightAchieved")] double WeightAchieved,
|
||||
[property: JsonPropertyName("participatingProviders")] IReadOnlyList<string>? ParticipatingProviders = null);
|
||||
|
||||
/// <summary>
|
||||
/// VEX rationale explaining the consensus decision.
|
||||
/// </summary>
|
||||
internal sealed record VexRationaleInfo(
|
||||
[property: JsonPropertyName("text")] string? Text = null,
|
||||
[property: JsonPropertyName("justifications")] IReadOnlyList<string>? Justifications = null,
|
||||
[property: JsonPropertyName("policyRules")] IReadOnlyList<string>? PolicyRules = null);
|
||||
|
||||
/// <summary>
|
||||
/// VEX signature status information.
|
||||
/// </summary>
|
||||
internal sealed record VexSignatureInfo(
|
||||
[property: JsonPropertyName("signed")] bool Signed,
|
||||
[property: JsonPropertyName("algorithm")] string? Algorithm = null,
|
||||
[property: JsonPropertyName("keyId")] string? KeyId = null,
|
||||
[property: JsonPropertyName("signedAt")] DateTimeOffset? SignedAt = null,
|
||||
[property: JsonPropertyName("verificationStatus")] string? VerificationStatus = null,
|
||||
[property: JsonPropertyName("certificateChain")] IReadOnlyList<string>? CertificateChain = null);
|
||||
|
||||
/// <summary>
|
||||
/// VEX evidence supporting the consensus decision.
|
||||
/// </summary>
|
||||
internal sealed record VexEvidenceInfo(
|
||||
[property: JsonPropertyName("type")] string Type,
|
||||
[property: JsonPropertyName("providerId")] string ProviderId,
|
||||
[property: JsonPropertyName("documentId")] string? DocumentId = null,
|
||||
[property: JsonPropertyName("documentDigest")] string? DocumentDigest = null,
|
||||
[property: JsonPropertyName("timestamp")] DateTimeOffset? Timestamp = null,
|
||||
[property: JsonPropertyName("content")] string? Content = null);
|
||||
|
||||
// CLI-VEX-30-003: VEX simulation models
|
||||
|
||||
/// <summary>
|
||||
/// VEX simulation request with trust/threshold overrides.
|
||||
/// </summary>
|
||||
internal sealed record VexSimulationRequest(
|
||||
[property: JsonPropertyName("vulnerabilityId")] string? VulnerabilityId = null,
|
||||
[property: JsonPropertyName("productKey")] string? ProductKey = null,
|
||||
[property: JsonPropertyName("purl")] string? Purl = null,
|
||||
[property: JsonPropertyName("trustOverrides")] IReadOnlyDictionary<string, double>? TrustOverrides = null,
|
||||
[property: JsonPropertyName("thresholdOverride")] double? ThresholdOverride = null,
|
||||
[property: JsonPropertyName("quorumOverride")] int? QuorumOverride = null,
|
||||
[property: JsonPropertyName("excludeProviders")] IReadOnlyList<string>? ExcludeProviders = null,
|
||||
[property: JsonPropertyName("includeOnly")] IReadOnlyList<string>? IncludeOnly = null);
|
||||
|
||||
/// <summary>
|
||||
/// VEX simulation response showing before/after comparison.
|
||||
/// </summary>
|
||||
internal sealed record VexSimulationResponse(
|
||||
[property: JsonPropertyName("items")] IReadOnlyList<VexSimulationResultItem> Items,
|
||||
[property: JsonPropertyName("parameters")] VexSimulationParameters Parameters,
|
||||
[property: JsonPropertyName("summary")] VexSimulationSummary Summary);
|
||||
|
||||
/// <summary>
|
||||
/// Individual VEX simulation result showing the delta.
|
||||
/// </summary>
|
||||
internal sealed record VexSimulationResultItem(
|
||||
[property: JsonPropertyName("vulnerabilityId")] string VulnerabilityId,
|
||||
[property: JsonPropertyName("product")] VexProductInfo Product,
|
||||
[property: JsonPropertyName("before")] VexSimulationState Before,
|
||||
[property: JsonPropertyName("after")] VexSimulationState After,
|
||||
[property: JsonPropertyName("changed")] bool Changed,
|
||||
[property: JsonPropertyName("changeType")] string? ChangeType = null);
|
||||
|
||||
/// <summary>
|
||||
/// VEX state for simulation comparison.
|
||||
/// </summary>
|
||||
internal sealed record VexSimulationState(
|
||||
[property: JsonPropertyName("status")] string Status,
|
||||
[property: JsonPropertyName("quorumAchieved")] int QuorumAchieved,
|
||||
[property: JsonPropertyName("weightAchieved")] double WeightAchieved,
|
||||
[property: JsonPropertyName("sources")] IReadOnlyList<string>? Sources = null);
|
||||
|
||||
/// <summary>
|
||||
/// Parameters used in the simulation.
|
||||
/// </summary>
|
||||
internal sealed record VexSimulationParameters(
|
||||
[property: JsonPropertyName("threshold")] double Threshold,
|
||||
[property: JsonPropertyName("quorum")] int Quorum,
|
||||
[property: JsonPropertyName("trustWeights")] IReadOnlyDictionary<string, double>? TrustWeights = null,
|
||||
[property: JsonPropertyName("excludedProviders")] IReadOnlyList<string>? ExcludedProviders = null);
|
||||
|
||||
/// <summary>
|
||||
/// Summary of simulation results.
|
||||
/// </summary>
|
||||
internal sealed record VexSimulationSummary(
|
||||
[property: JsonPropertyName("totalEvaluated")] int TotalEvaluated,
|
||||
[property: JsonPropertyName("totalChanged")] int TotalChanged,
|
||||
[property: JsonPropertyName("statusUpgrades")] int StatusUpgrades,
|
||||
[property: JsonPropertyName("statusDowngrades")] int StatusDowngrades,
|
||||
[property: JsonPropertyName("noChange")] int NoChange);
|
||||
|
||||
// CLI-VEX-30-004: VEX export models
|
||||
|
||||
/// <summary>
|
||||
/// VEX export request parameters.
|
||||
/// </summary>
|
||||
internal sealed record VexExportRequest(
|
||||
[property: JsonPropertyName("vulnerabilityIds")] IReadOnlyList<string>? VulnerabilityIds = null,
|
||||
[property: JsonPropertyName("productKeys")] IReadOnlyList<string>? ProductKeys = null,
|
||||
[property: JsonPropertyName("purls")] IReadOnlyList<string>? Purls = null,
|
||||
[property: JsonPropertyName("statuses")] IReadOnlyList<string>? Statuses = null,
|
||||
[property: JsonPropertyName("policyVersion")] string? PolicyVersion = null,
|
||||
[property: JsonPropertyName("signed")] bool Signed = true,
|
||||
[property: JsonPropertyName("format")] string Format = "ndjson");
|
||||
|
||||
/// <summary>
|
||||
/// VEX export response with download information.
|
||||
/// </summary>
|
||||
internal sealed record VexExportResponse(
|
||||
[property: JsonPropertyName("exportId")] string ExportId,
|
||||
[property: JsonPropertyName("downloadUrl")] string? DownloadUrl = null,
|
||||
[property: JsonPropertyName("format")] string Format = "ndjson",
|
||||
[property: JsonPropertyName("itemCount")] int ItemCount = 0,
|
||||
[property: JsonPropertyName("signed")] bool Signed = false,
|
||||
[property: JsonPropertyName("signatureAlgorithm")] string? SignatureAlgorithm = null,
|
||||
[property: JsonPropertyName("signatureKeyId")] string? SignatureKeyId = null,
|
||||
[property: JsonPropertyName("digest")] string? Digest = null,
|
||||
[property: JsonPropertyName("digestAlgorithm")] string? DigestAlgorithm = null,
|
||||
[property: JsonPropertyName("expiresAt")] DateTimeOffset? ExpiresAt = null);
|
||||
|
||||
/// <summary>
|
||||
/// VEX export signature verification request.
|
||||
/// </summary>
|
||||
internal sealed record VexExportVerifyRequest(
|
||||
[property: JsonPropertyName("filePath")] string FilePath,
|
||||
[property: JsonPropertyName("signaturePath")] string? SignaturePath = null,
|
||||
[property: JsonPropertyName("expectedDigest")] string? ExpectedDigest = null,
|
||||
[property: JsonPropertyName("publicKeyPath")] string? PublicKeyPath = null);
|
||||
|
||||
/// <summary>
|
||||
/// VEX export signature verification result.
|
||||
/// </summary>
|
||||
internal sealed record VexExportVerifyResult(
|
||||
[property: JsonPropertyName("valid")] bool Valid,
|
||||
[property: JsonPropertyName("signatureStatus")] string SignatureStatus,
|
||||
[property: JsonPropertyName("digestMatch")] bool? DigestMatch = null,
|
||||
[property: JsonPropertyName("actualDigest")] string? ActualDigest = null,
|
||||
[property: JsonPropertyName("expectedDigest")] string? ExpectedDigest = null,
|
||||
[property: JsonPropertyName("keyId")] string? KeyId = null,
|
||||
[property: JsonPropertyName("signedAt")] DateTimeOffset? SignedAt = null,
|
||||
[property: JsonPropertyName("errors")] IReadOnlyList<string>? Errors = null);
|
||||
291
src/Cli/StellaOps.Cli/Services/Models/VulnModels.cs
Normal file
291
src/Cli/StellaOps.Cli/Services/Models/VulnModels.cs
Normal file
@@ -0,0 +1,291 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace StellaOps.Cli.Services.Models;
|
||||
|
||||
// CLI-VULN-29-001: Vulnerability Explorer models for CLI
|
||||
|
||||
/// <summary>
|
||||
/// Vulnerability list request parameters.
|
||||
/// </summary>
|
||||
internal sealed record VulnListRequest(
|
||||
[property: JsonPropertyName("vulnerabilityId")] string? VulnerabilityId = null,
|
||||
[property: JsonPropertyName("severity")] string? Severity = null,
|
||||
[property: JsonPropertyName("status")] string? Status = null,
|
||||
[property: JsonPropertyName("purl")] string? Purl = null,
|
||||
[property: JsonPropertyName("cpe")] string? Cpe = null,
|
||||
[property: JsonPropertyName("sbomId")] string? SbomId = null,
|
||||
[property: JsonPropertyName("policyId")] string? PolicyId = null,
|
||||
[property: JsonPropertyName("policyVersion")] int? PolicyVersion = null,
|
||||
[property: JsonPropertyName("groupBy")] string? GroupBy = null,
|
||||
[property: JsonPropertyName("limit")] int? Limit = null,
|
||||
[property: JsonPropertyName("offset")] int? Offset = null,
|
||||
[property: JsonPropertyName("cursor")] string? Cursor = null);
|
||||
|
||||
/// <summary>
|
||||
/// Paginated vulnerability list response.
|
||||
/// </summary>
|
||||
internal sealed record VulnListResponse(
|
||||
[property: JsonPropertyName("items")] IReadOnlyList<VulnItem> Items,
|
||||
[property: JsonPropertyName("total")] int Total,
|
||||
[property: JsonPropertyName("limit")] int Limit,
|
||||
[property: JsonPropertyName("offset")] int Offset,
|
||||
[property: JsonPropertyName("hasMore")] bool HasMore,
|
||||
[property: JsonPropertyName("nextCursor")] string? NextCursor = null,
|
||||
[property: JsonPropertyName("grouping")] VulnGroupingInfo? Grouping = null);
|
||||
|
||||
/// <summary>
|
||||
/// Individual vulnerability item from the explorer.
|
||||
/// </summary>
|
||||
internal sealed record VulnItem(
|
||||
[property: JsonPropertyName("vulnerabilityId")] string VulnerabilityId,
|
||||
[property: JsonPropertyName("status")] string Status,
|
||||
[property: JsonPropertyName("severity")] VulnSeverityInfo Severity,
|
||||
[property: JsonPropertyName("affectedPackages")] IReadOnlyList<VulnAffectedPackage> AffectedPackages,
|
||||
[property: JsonPropertyName("vexStatus")] string? VexStatus = null,
|
||||
[property: JsonPropertyName("policyFindingId")] string? PolicyFindingId = null,
|
||||
[property: JsonPropertyName("aliases")] IReadOnlyList<string>? Aliases = null,
|
||||
[property: JsonPropertyName("summary")] string? Summary = null,
|
||||
[property: JsonPropertyName("publishedAt")] DateTimeOffset? PublishedAt = null,
|
||||
[property: JsonPropertyName("updatedAt")] DateTimeOffset? UpdatedAt = null,
|
||||
[property: JsonPropertyName("assignee")] string? Assignee = null,
|
||||
[property: JsonPropertyName("dueDate")] DateTimeOffset? DueDate = null,
|
||||
[property: JsonPropertyName("tags")] IReadOnlyList<string>? Tags = null);
|
||||
|
||||
/// <summary>
|
||||
/// Vulnerability severity information.
|
||||
/// </summary>
|
||||
internal sealed record VulnSeverityInfo(
|
||||
[property: JsonPropertyName("level")] string Level,
|
||||
[property: JsonPropertyName("score")] double? Score = null,
|
||||
[property: JsonPropertyName("vector")] string? Vector = null,
|
||||
[property: JsonPropertyName("source")] string? Source = null);
|
||||
|
||||
/// <summary>
|
||||
/// Affected package information.
|
||||
/// </summary>
|
||||
internal sealed record VulnAffectedPackage(
|
||||
[property: JsonPropertyName("purl")] string? Purl = null,
|
||||
[property: JsonPropertyName("cpe")] string? Cpe = null,
|
||||
[property: JsonPropertyName("name")] string? Name = null,
|
||||
[property: JsonPropertyName("version")] string? Version = null,
|
||||
[property: JsonPropertyName("fixedIn")] string? FixedIn = null,
|
||||
[property: JsonPropertyName("sbomId")] string? SbomId = null,
|
||||
[property: JsonPropertyName("pathCount")] int? PathCount = null);
|
||||
|
||||
/// <summary>
|
||||
/// Grouping information for aggregated results.
|
||||
/// </summary>
|
||||
internal sealed record VulnGroupingInfo(
|
||||
[property: JsonPropertyName("field")] string Field,
|
||||
[property: JsonPropertyName("groups")] IReadOnlyList<VulnGroup> Groups);
|
||||
|
||||
/// <summary>
|
||||
/// A group in aggregated results.
|
||||
/// </summary>
|
||||
internal sealed record VulnGroup(
|
||||
[property: JsonPropertyName("key")] string Key,
|
||||
[property: JsonPropertyName("count")] int Count,
|
||||
[property: JsonPropertyName("criticalCount")] int? CriticalCount = null,
|
||||
[property: JsonPropertyName("highCount")] int? HighCount = null,
|
||||
[property: JsonPropertyName("mediumCount")] int? MediumCount = null,
|
||||
[property: JsonPropertyName("lowCount")] int? LowCount = null);
|
||||
|
||||
// CLI-VULN-29-002: Vulnerability detail models
|
||||
|
||||
/// <summary>
|
||||
/// Detailed vulnerability response including evidence, rationale, paths, and ledger.
|
||||
/// </summary>
|
||||
internal sealed record VulnDetailResponse(
|
||||
[property: JsonPropertyName("vulnerabilityId")] string VulnerabilityId,
|
||||
[property: JsonPropertyName("status")] string Status,
|
||||
[property: JsonPropertyName("severity")] VulnSeverityInfo Severity,
|
||||
[property: JsonPropertyName("affectedPackages")] IReadOnlyList<VulnAffectedPackage> AffectedPackages,
|
||||
[property: JsonPropertyName("vexStatus")] string? VexStatus = null,
|
||||
[property: JsonPropertyName("policyFindingId")] string? PolicyFindingId = null,
|
||||
[property: JsonPropertyName("aliases")] IReadOnlyList<string>? Aliases = null,
|
||||
[property: JsonPropertyName("summary")] string? Summary = null,
|
||||
[property: JsonPropertyName("description")] string? Description = null,
|
||||
[property: JsonPropertyName("publishedAt")] DateTimeOffset? PublishedAt = null,
|
||||
[property: JsonPropertyName("updatedAt")] DateTimeOffset? UpdatedAt = null,
|
||||
[property: JsonPropertyName("assignee")] string? Assignee = null,
|
||||
[property: JsonPropertyName("dueDate")] DateTimeOffset? DueDate = null,
|
||||
[property: JsonPropertyName("tags")] IReadOnlyList<string>? Tags = null,
|
||||
[property: JsonPropertyName("evidence")] IReadOnlyList<VulnEvidenceInfo>? Evidence = null,
|
||||
[property: JsonPropertyName("policyRationale")] VulnPolicyRationale? PolicyRationale = null,
|
||||
[property: JsonPropertyName("dependencyPaths")] IReadOnlyList<VulnDependencyPath>? DependencyPaths = null,
|
||||
[property: JsonPropertyName("ledger")] IReadOnlyList<VulnLedgerEntry>? Ledger = null,
|
||||
[property: JsonPropertyName("references")] IReadOnlyList<VulnReference>? References = null);
|
||||
|
||||
/// <summary>
|
||||
/// Evidence supporting the vulnerability assessment.
|
||||
/// </summary>
|
||||
internal sealed record VulnEvidenceInfo(
|
||||
[property: JsonPropertyName("type")] string Type,
|
||||
[property: JsonPropertyName("source")] string Source,
|
||||
[property: JsonPropertyName("documentId")] string? DocumentId = null,
|
||||
[property: JsonPropertyName("documentDigest")] string? DocumentDigest = null,
|
||||
[property: JsonPropertyName("timestamp")] DateTimeOffset? Timestamp = null,
|
||||
[property: JsonPropertyName("content")] string? Content = null);
|
||||
|
||||
/// <summary>
|
||||
/// Policy rationale explaining the status decision.
|
||||
/// </summary>
|
||||
internal sealed record VulnPolicyRationale(
|
||||
[property: JsonPropertyName("policyId")] string PolicyId,
|
||||
[property: JsonPropertyName("policyVersion")] int PolicyVersion,
|
||||
[property: JsonPropertyName("rules")] IReadOnlyList<VulnPolicyRuleResult>? Rules = null,
|
||||
[property: JsonPropertyName("summary")] string? Summary = null);
|
||||
|
||||
/// <summary>
|
||||
/// Result of a policy rule evaluation.
|
||||
/// </summary>
|
||||
internal sealed record VulnPolicyRuleResult(
|
||||
[property: JsonPropertyName("rule")] string Rule,
|
||||
[property: JsonPropertyName("result")] string Result,
|
||||
[property: JsonPropertyName("weight")] double? Weight = null,
|
||||
[property: JsonPropertyName("reason")] string? Reason = null);
|
||||
|
||||
/// <summary>
|
||||
/// Dependency path showing how the vulnerable package is included.
|
||||
/// </summary>
|
||||
internal sealed record VulnDependencyPath(
|
||||
[property: JsonPropertyName("path")] IReadOnlyList<string> Path,
|
||||
[property: JsonPropertyName("sbomId")] string? SbomId = null,
|
||||
[property: JsonPropertyName("depth")] int? Depth = null);
|
||||
|
||||
/// <summary>
|
||||
/// Ledger entry tracking vulnerability workflow history.
|
||||
/// </summary>
|
||||
internal sealed record VulnLedgerEntry(
|
||||
[property: JsonPropertyName("timestamp")] DateTimeOffset Timestamp,
|
||||
[property: JsonPropertyName("action")] string Action,
|
||||
[property: JsonPropertyName("actor")] string? Actor = null,
|
||||
[property: JsonPropertyName("fromStatus")] string? FromStatus = null,
|
||||
[property: JsonPropertyName("toStatus")] string? ToStatus = null,
|
||||
[property: JsonPropertyName("comment")] string? Comment = null,
|
||||
[property: JsonPropertyName("metadata")] IReadOnlyDictionary<string, string>? Metadata = null);
|
||||
|
||||
/// <summary>
|
||||
/// Reference link for the vulnerability.
|
||||
/// </summary>
|
||||
internal sealed record VulnReference(
|
||||
[property: JsonPropertyName("type")] string Type,
|
||||
[property: JsonPropertyName("url")] string Url,
|
||||
[property: JsonPropertyName("title")] string? Title = null);
|
||||
|
||||
// CLI-VULN-29-003: Vulnerability workflow models
|
||||
|
||||
/// <summary>
|
||||
/// Workflow action request for vulnerability operations.
|
||||
/// </summary>
|
||||
internal sealed record VulnWorkflowRequest(
|
||||
[property: JsonPropertyName("action")] string Action,
|
||||
[property: JsonPropertyName("vulnerabilityIds")] IReadOnlyList<string>? VulnerabilityIds = null,
|
||||
[property: JsonPropertyName("filter")] VulnFilterSpec? Filter = null,
|
||||
[property: JsonPropertyName("assignee")] string? Assignee = null,
|
||||
[property: JsonPropertyName("comment")] string? Comment = null,
|
||||
[property: JsonPropertyName("dueDate")] DateTimeOffset? DueDate = null,
|
||||
[property: JsonPropertyName("justification")] string? Justification = null,
|
||||
[property: JsonPropertyName("fixVersion")] string? FixVersion = null,
|
||||
[property: JsonPropertyName("idempotencyKey")] string? IdempotencyKey = null);
|
||||
|
||||
/// <summary>
|
||||
/// Filter specification for bulk workflow operations.
|
||||
/// </summary>
|
||||
internal sealed record VulnFilterSpec(
|
||||
[property: JsonPropertyName("severity")] string? Severity = null,
|
||||
[property: JsonPropertyName("status")] string? Status = null,
|
||||
[property: JsonPropertyName("purl")] string? Purl = null,
|
||||
[property: JsonPropertyName("sbomId")] string? SbomId = null,
|
||||
[property: JsonPropertyName("policyId")] string? PolicyId = null);
|
||||
|
||||
/// <summary>
|
||||
/// Workflow action response with affected items.
|
||||
/// </summary>
|
||||
internal sealed record VulnWorkflowResponse(
|
||||
[property: JsonPropertyName("success")] bool Success,
|
||||
[property: JsonPropertyName("action")] string Action,
|
||||
[property: JsonPropertyName("affectedCount")] int AffectedCount,
|
||||
[property: JsonPropertyName("affectedIds")] IReadOnlyList<string>? AffectedIds = null,
|
||||
[property: JsonPropertyName("errors")] IReadOnlyList<VulnWorkflowError>? Errors = null,
|
||||
[property: JsonPropertyName("idempotencyKey")] string? IdempotencyKey = null);
|
||||
|
||||
/// <summary>
|
||||
/// Error detail for workflow operations.
|
||||
/// </summary>
|
||||
internal sealed record VulnWorkflowError(
|
||||
[property: JsonPropertyName("vulnerabilityId")] string VulnerabilityId,
|
||||
[property: JsonPropertyName("code")] string Code,
|
||||
[property: JsonPropertyName("message")] string Message);
|
||||
|
||||
// CLI-VULN-29-004: Vulnerability simulation models
|
||||
|
||||
/// <summary>
|
||||
/// Simulation request for policy/VEX changes.
|
||||
/// </summary>
|
||||
internal sealed record VulnSimulationRequest(
|
||||
[property: JsonPropertyName("policyId")] string? PolicyId = null,
|
||||
[property: JsonPropertyName("policyVersion")] int? PolicyVersion = null,
|
||||
[property: JsonPropertyName("vexOverrides")] IReadOnlyDictionary<string, string>? VexOverrides = null,
|
||||
[property: JsonPropertyName("severityThreshold")] string? SeverityThreshold = null,
|
||||
[property: JsonPropertyName("sbomIds")] IReadOnlyList<string>? SbomIds = null,
|
||||
[property: JsonPropertyName("outputMarkdown")] bool OutputMarkdown = false);
|
||||
|
||||
/// <summary>
|
||||
/// Simulation response showing deltas.
|
||||
/// </summary>
|
||||
internal sealed record VulnSimulationResponse(
|
||||
[property: JsonPropertyName("items")] IReadOnlyList<VulnSimulationDelta> Items,
|
||||
[property: JsonPropertyName("summary")] VulnSimulationSummary Summary,
|
||||
[property: JsonPropertyName("markdownReport")] string? MarkdownReport = null);
|
||||
|
||||
/// <summary>
|
||||
/// Individual delta in simulation results.
|
||||
/// </summary>
|
||||
internal sealed record VulnSimulationDelta(
|
||||
[property: JsonPropertyName("vulnerabilityId")] string VulnerabilityId,
|
||||
[property: JsonPropertyName("beforeStatus")] string BeforeStatus,
|
||||
[property: JsonPropertyName("afterStatus")] string AfterStatus,
|
||||
[property: JsonPropertyName("changed")] bool Changed,
|
||||
[property: JsonPropertyName("changeReason")] string? ChangeReason = null);
|
||||
|
||||
/// <summary>
|
||||
/// Summary of simulation results.
|
||||
/// </summary>
|
||||
internal sealed record VulnSimulationSummary(
|
||||
[property: JsonPropertyName("totalEvaluated")] int TotalEvaluated,
|
||||
[property: JsonPropertyName("totalChanged")] int TotalChanged,
|
||||
[property: JsonPropertyName("statusUpgrades")] int StatusUpgrades,
|
||||
[property: JsonPropertyName("statusDowngrades")] int StatusDowngrades,
|
||||
[property: JsonPropertyName("noChange")] int NoChange);
|
||||
|
||||
// CLI-VULN-29-005: Vulnerability export models
|
||||
|
||||
/// <summary>
|
||||
/// Export request for vulnerability evidence bundles.
|
||||
/// </summary>
|
||||
internal sealed record VulnExportRequest(
|
||||
[property: JsonPropertyName("vulnerabilityIds")] IReadOnlyList<string>? VulnerabilityIds = null,
|
||||
[property: JsonPropertyName("sbomIds")] IReadOnlyList<string>? SbomIds = null,
|
||||
[property: JsonPropertyName("policyId")] string? PolicyId = null,
|
||||
[property: JsonPropertyName("format")] string Format = "ndjson",
|
||||
[property: JsonPropertyName("includeEvidence")] bool IncludeEvidence = true,
|
||||
[property: JsonPropertyName("includeLedger")] bool IncludeLedger = true,
|
||||
[property: JsonPropertyName("signed")] bool Signed = true);
|
||||
|
||||
/// <summary>
|
||||
/// Export response with download information.
|
||||
/// </summary>
|
||||
internal sealed record VulnExportResponse(
|
||||
[property: JsonPropertyName("exportId")] string ExportId,
|
||||
[property: JsonPropertyName("downloadUrl")] string? DownloadUrl = null,
|
||||
[property: JsonPropertyName("format")] string Format = "ndjson",
|
||||
[property: JsonPropertyName("itemCount")] int ItemCount = 0,
|
||||
[property: JsonPropertyName("signed")] bool Signed = false,
|
||||
[property: JsonPropertyName("signatureAlgorithm")] string? SignatureAlgorithm = null,
|
||||
[property: JsonPropertyName("signatureKeyId")] string? SignatureKeyId = null,
|
||||
[property: JsonPropertyName("digest")] string? Digest = null,
|
||||
[property: JsonPropertyName("digestAlgorithm")] string? DigestAlgorithm = null,
|
||||
[property: JsonPropertyName("expiresAt")] DateTimeOffset? ExpiresAt = null);
|
||||
Reference in New Issue
Block a user