new advisories work and features gaps work
This commit is contained in:
@@ -44,7 +44,17 @@ public sealed record RekorEntryRefDto(
|
||||
long? LogIndex = null,
|
||||
string? LogId = null,
|
||||
string? Uuid = null,
|
||||
long? IntegratedTime = null);
|
||||
long? IntegratedTime = null,
|
||||
/// <summary>
|
||||
/// Rekor integrated time as RFC3339 timestamp (ISO 8601 format).
|
||||
/// Sprint: SPRINT_20260112_004_FINDINGS_evidence_graph_rekor_time (FIND-REKOR-002)
|
||||
/// </summary>
|
||||
DateTimeOffset? IntegratedTimeRfc3339 = null,
|
||||
/// <summary>
|
||||
/// Full URL to the Rekor entry for UI linking.
|
||||
/// Sprint: SPRINT_20260112_004_FINDINGS_evidence_graph_rekor_time (FIND-REKOR-002)
|
||||
/// </summary>
|
||||
string? EntryUrl = null);
|
||||
|
||||
/// <summary>
|
||||
/// Result of attestation verification.
|
||||
@@ -183,11 +193,14 @@ public static class AttestationPointerMappings
|
||||
|
||||
public static RekorEntryRef ToModel(this RekorEntryRefDto dto)
|
||||
{
|
||||
// Sprint: SPRINT_20260112_004_FINDINGS_evidence_graph_rekor_time (FIND-REKOR-002)
|
||||
return new RekorEntryRef(
|
||||
dto.LogIndex,
|
||||
dto.LogId,
|
||||
dto.Uuid,
|
||||
dto.IntegratedTime);
|
||||
dto.IntegratedTime,
|
||||
dto.IntegratedTimeRfc3339,
|
||||
dto.EntryUrl);
|
||||
}
|
||||
|
||||
public static VerificationResult ToModel(this VerificationResultDto dto)
|
||||
@@ -253,11 +266,14 @@ public static class AttestationPointerMappings
|
||||
|
||||
public static RekorEntryRefDto ToDto(this RekorEntryRef model)
|
||||
{
|
||||
// Sprint: SPRINT_20260112_004_FINDINGS_evidence_graph_rekor_time (FIND-REKOR-002)
|
||||
return new RekorEntryRefDto(
|
||||
model.LogIndex,
|
||||
model.LogId,
|
||||
model.Uuid,
|
||||
model.IntegratedTime);
|
||||
model.IntegratedTime,
|
||||
model.IntegratedTimeRfc3339,
|
||||
model.EntryUrl);
|
||||
}
|
||||
|
||||
public static VerificationResultDto ToDto(this VerificationResult model)
|
||||
|
||||
@@ -155,6 +155,126 @@ public sealed record EvidenceWeightedScoreResponse
|
||||
/// Whether this result came from cache.
|
||||
/// </summary>
|
||||
public bool FromCache { get; init; }
|
||||
|
||||
// Sprint: SPRINT_20260112_004_BE_findings_scoring_attested_reduction (EWS-API-001)
|
||||
|
||||
/// <summary>
|
||||
/// Reduction profile metadata when attested reduction is active.
|
||||
/// </summary>
|
||||
public ReductionProfileDto? ReductionProfile { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether this finding has a hard-fail status (must be addressed).
|
||||
/// </summary>
|
||||
public bool HardFail { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Reason for short-circuit if score was set to 0 due to attested evidence.
|
||||
/// </summary>
|
||||
public string? ShortCircuitReason { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Anchor metadata for the evidence used in scoring.
|
||||
/// </summary>
|
||||
public EvidenceAnchorDto? Anchor { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reduction profile metadata for attested scoring.
|
||||
/// Sprint: SPRINT_20260112_004_BE_findings_scoring_attested_reduction (EWS-API-001)
|
||||
/// </summary>
|
||||
public sealed record ReductionProfileDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether reduction mode is enabled.
|
||||
/// </summary>
|
||||
[JsonPropertyName("enabled")]
|
||||
public required bool Enabled { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Reduction mode (e.g., "aggressive", "conservative", "custom").
|
||||
/// </summary>
|
||||
[JsonPropertyName("mode")]
|
||||
public string? Mode { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Policy profile ID used.
|
||||
/// </summary>
|
||||
[JsonPropertyName("profileId")]
|
||||
public string? ProfileId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Maximum reduction percentage allowed.
|
||||
/// </summary>
|
||||
[JsonPropertyName("maxReductionPercent")]
|
||||
public int? MaxReductionPercent { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether VEX anchoring is required.
|
||||
/// </summary>
|
||||
[JsonPropertyName("requireVexAnchoring")]
|
||||
public bool RequireVexAnchoring { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether Rekor verification is required.
|
||||
/// </summary>
|
||||
[JsonPropertyName("requireRekorVerification")]
|
||||
public bool RequireRekorVerification { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evidence anchor metadata for attested scoring.
|
||||
/// Sprint: SPRINT_20260112_004_BE_findings_scoring_attested_reduction (EWS-API-001)
|
||||
/// </summary>
|
||||
public sealed record EvidenceAnchorDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether the evidence is anchored (has attestation).
|
||||
/// </summary>
|
||||
[JsonPropertyName("anchored")]
|
||||
public required bool Anchored { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// DSSE envelope digest if anchored.
|
||||
/// </summary>
|
||||
[JsonPropertyName("envelopeDigest")]
|
||||
public string? EnvelopeDigest { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Predicate type of the attestation.
|
||||
/// </summary>
|
||||
[JsonPropertyName("predicateType")]
|
||||
public string? PredicateType { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Rekor log index if transparency-anchored.
|
||||
/// </summary>
|
||||
[JsonPropertyName("rekorLogIndex")]
|
||||
public long? RekorLogIndex { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Rekor entry ID if transparency-anchored.
|
||||
/// </summary>
|
||||
[JsonPropertyName("rekorEntryId")]
|
||||
public string? RekorEntryId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Scope of the attestation.
|
||||
/// </summary>
|
||||
[JsonPropertyName("scope")]
|
||||
public string? Scope { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Verification status of the anchor.
|
||||
/// </summary>
|
||||
[JsonPropertyName("verified")]
|
||||
public bool? Verified { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// When the attestation was created.
|
||||
/// </summary>
|
||||
[JsonPropertyName("attestedAt")]
|
||||
public DateTimeOffset? AttestedAt { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -73,7 +73,50 @@ public sealed record RekorEntryRef(
|
||||
long? LogIndex = null,
|
||||
string? LogId = null,
|
||||
string? Uuid = null,
|
||||
long? IntegratedTime = null);
|
||||
long? IntegratedTime = null,
|
||||
/// <summary>
|
||||
/// Rekor integrated time as RFC3339 timestamp (ISO 8601 format).
|
||||
/// Sprint: SPRINT_20260112_004_FINDINGS_evidence_graph_rekor_time (FIND-REKOR-001)
|
||||
/// </summary>
|
||||
DateTimeOffset? IntegratedTimeRfc3339 = null,
|
||||
/// <summary>
|
||||
/// Full URL to the Rekor entry for UI linking.
|
||||
/// Sprint: SPRINT_20260112_004_FINDINGS_evidence_graph_rekor_time (FIND-REKOR-001)
|
||||
/// </summary>
|
||||
string? EntryUrl = null)
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the integrated time as DateTimeOffset.
|
||||
/// Prioritizes IntegratedTimeRfc3339 if set, otherwise converts IntegratedTime from Unix epoch.
|
||||
/// </summary>
|
||||
public DateTimeOffset? GetIntegratedTimeAsDateTime()
|
||||
{
|
||||
if (IntegratedTimeRfc3339.HasValue)
|
||||
return IntegratedTimeRfc3339;
|
||||
|
||||
if (IntegratedTime.HasValue)
|
||||
return DateTimeOffset.FromUnixTimeSeconds(IntegratedTime.Value);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Rekor entry URL, constructing from UUID if not explicitly set.
|
||||
/// </summary>
|
||||
public string? GetEntryUrl(string rekorBaseUrl = "https://rekor.sigstore.dev")
|
||||
{
|
||||
if (!string.IsNullOrEmpty(EntryUrl))
|
||||
return EntryUrl;
|
||||
|
||||
if (!string.IsNullOrEmpty(Uuid))
|
||||
return $"{rekorBaseUrl}/api/v1/log/entries/{Uuid}";
|
||||
|
||||
if (!string.IsNullOrEmpty(LogId) && LogIndex.HasValue)
|
||||
return $"{rekorBaseUrl}/api/v1/log/entries?logIndex={LogIndex.Value}";
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Result of attestation verification.
|
||||
|
||||
Reference in New Issue
Block a user