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
Export Center CI / export-ci (push) Has been cancelled
devportal-offline / build-offline (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
Export Center CI / export-ci (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
This commit is contained in:
@@ -83,18 +83,30 @@ internal static class PolicyEndpoints
|
||||
return operation;
|
||||
});
|
||||
|
||||
policyGroup.MapPost("/overlay", HandlePolicyOverlayAsync)
|
||||
.WithName("scanner.policy.overlay")
|
||||
.Produces<PolicyOverlayResponseDto>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status400BadRequest)
|
||||
.RequireAuthorization(ScannerPolicies.Reports)
|
||||
.WithOpenApi(operation =>
|
||||
{
|
||||
operation.Summary = "Request policy overlays for graph nodes.";
|
||||
operation.Description = "Returns deterministic policy overlays with runtime evidence for graph nodes (Cartographer integration). Overlay IDs are computed as sha256(tenant|nodeId|overlayKind).";
|
||||
return operation;
|
||||
});
|
||||
}
|
||||
policyGroup.MapPost("/overlay", HandlePolicyOverlayAsync)
|
||||
.WithName("scanner.policy.overlay")
|
||||
.Produces<PolicyOverlayResponseDto>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status400BadRequest)
|
||||
.RequireAuthorization(ScannerPolicies.Reports)
|
||||
.WithOpenApi(operation =>
|
||||
{
|
||||
operation.Summary = "Request policy overlays for graph nodes.";
|
||||
operation.Description = "Returns deterministic policy overlays with runtime evidence for graph nodes (Cartographer integration). Overlay IDs are computed as sha256(tenant|nodeId|overlayKind).";
|
||||
return operation;
|
||||
});
|
||||
|
||||
policyGroup.MapPost("/linksets", HandleLinksetSummaryAsync)
|
||||
.WithName("scanner.policy.linksets")
|
||||
.Produces<LinksetSummaryResponseDto>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status400BadRequest)
|
||||
.RequireAuthorization(ScannerPolicies.Reports)
|
||||
.WithOpenApi(operation =>
|
||||
{
|
||||
operation.Summary = "Fetch advisory linkset summaries with optional policy overlay.";
|
||||
operation.Description = "Returns linkset severities/conflicts for advisory IDs and, when requested, runtime policy overlay for the provided image digest.";
|
||||
return operation;
|
||||
});
|
||||
}
|
||||
|
||||
private static IResult HandleSchemaAsync(HttpContext context)
|
||||
{
|
||||
@@ -188,11 +200,11 @@ internal static class PolicyEndpoints
|
||||
return Json(payload);
|
||||
}
|
||||
|
||||
private static async Task<IResult> HandleRuntimePolicyAsync(
|
||||
RuntimePolicyRequestDto request,
|
||||
IRuntimePolicyService runtimePolicyService,
|
||||
HttpContext context,
|
||||
CancellationToken cancellationToken)
|
||||
private static async Task<IResult> HandleRuntimePolicyAsync(
|
||||
RuntimePolicyRequestDto request,
|
||||
IRuntimePolicyService runtimePolicyService,
|
||||
HttpContext context,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(request);
|
||||
ArgumentNullException.ThrowIfNull(runtimePolicyService);
|
||||
@@ -273,8 +285,96 @@ internal static class PolicyEndpoints
|
||||
var evaluation = await runtimePolicyService.EvaluateAsync(evaluationRequest, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var resultPayload = MapRuntimePolicyResponse(evaluation);
|
||||
return Json(resultPayload);
|
||||
}
|
||||
return Json(resultPayload);
|
||||
}
|
||||
|
||||
private static async Task<IResult> HandleLinksetSummaryAsync(
|
||||
LinksetSummaryRequestDto request,
|
||||
ILinksetResolver linksetResolver,
|
||||
IRuntimePolicyService runtimePolicyService,
|
||||
HttpContext context,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(request);
|
||||
ArgumentNullException.ThrowIfNull(linksetResolver);
|
||||
ArgumentNullException.ThrowIfNull(runtimePolicyService);
|
||||
|
||||
if (request.AdvisoryIds is null || request.AdvisoryIds.Count == 0)
|
||||
{
|
||||
return ProblemResultFactory.Create(
|
||||
context,
|
||||
ProblemTypes.Validation,
|
||||
"Invalid linkset request",
|
||||
StatusCodes.Status400BadRequest,
|
||||
detail: "advisoryIds must include at least one value.");
|
||||
}
|
||||
|
||||
if (request.IncludePolicyOverlay && string.IsNullOrWhiteSpace(request.ImageDigest))
|
||||
{
|
||||
return ProblemResultFactory.Create(
|
||||
context,
|
||||
ProblemTypes.Validation,
|
||||
"Invalid linkset request",
|
||||
StatusCodes.Status400BadRequest,
|
||||
detail: "imageDigest is required when includePolicyOverlay is true.");
|
||||
}
|
||||
|
||||
var linksets = await linksetResolver.ResolveByAdvisoryIdsAsync(request.AdvisoryIds, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
RuntimePolicyImageResponseDto? policy = null;
|
||||
if (request.IncludePolicyOverlay && !string.IsNullOrWhiteSpace(request.ImageDigest))
|
||||
{
|
||||
var runtimeRequest = new RuntimePolicyRequestDto
|
||||
{
|
||||
Images = new[] { request.ImageDigest!.Trim() }
|
||||
};
|
||||
|
||||
var evaluation = await runtimePolicyService.EvaluateAsync(
|
||||
new RuntimePolicyEvaluationRequest(
|
||||
runtimeRequest.Namespace,
|
||||
new ReadOnlyDictionary<string, string>(new Dictionary<string, string>(StringComparer.Ordinal)),
|
||||
runtimeRequest.Images),
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (evaluation.Results.TryGetValue(request.ImageDigest!.Trim(), out var decision))
|
||||
{
|
||||
RuntimePolicyRekorDto? rekor = null;
|
||||
if (decision.Rekor is not null)
|
||||
{
|
||||
rekor = new RuntimePolicyRekorDto
|
||||
{
|
||||
Uuid = decision.Rekor.Uuid,
|
||||
Url = decision.Rekor.Url,
|
||||
Verified = decision.Rekor.Verified
|
||||
};
|
||||
}
|
||||
|
||||
policy = new RuntimePolicyImageResponseDto
|
||||
{
|
||||
PolicyVerdict = decision.PolicyVerdict.ToString().ToLowerInvariant(),
|
||||
Signed = decision.Signed,
|
||||
HasSbomReferrers = decision.HasSbomReferrers,
|
||||
HasSbomLegacy = decision.HasSbomReferrers,
|
||||
Reasons = decision.Reasons,
|
||||
Rekor = rekor,
|
||||
Confidence = Math.Round(decision.Confidence, 6, MidpointRounding.AwayFromZero),
|
||||
Quieted = decision.Quieted,
|
||||
QuietedBy = decision.QuietedBy,
|
||||
Metadata = decision.Metadata is { Count: > 0 } ? JsonSerializer.Serialize(decision.Metadata) : null,
|
||||
BuildIds = decision.BuildIds,
|
||||
Linksets = decision.Linksets
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
var response = new LinksetSummaryResponseDto
|
||||
{
|
||||
Linksets = linksets,
|
||||
Policy = policy
|
||||
};
|
||||
|
||||
return Json(response);
|
||||
}
|
||||
|
||||
private static string NormalizeSegment(string segment)
|
||||
{
|
||||
@@ -322,15 +422,16 @@ internal static class PolicyEndpoints
|
||||
Signed = decision.Signed,
|
||||
HasSbomReferrers = decision.HasSbomReferrers,
|
||||
HasSbomLegacy = decision.HasSbomReferrers,
|
||||
Reasons = decision.Reasons.ToArray(),
|
||||
Rekor = rekor,
|
||||
Confidence = Math.Round(decision.Confidence, 6, MidpointRounding.AwayFromZero),
|
||||
Quieted = decision.Quieted,
|
||||
QuietedBy = decision.QuietedBy,
|
||||
Metadata = metadata,
|
||||
BuildIds = decision.BuildIds is { Count: > 0 } ? decision.BuildIds.ToArray() : null
|
||||
};
|
||||
}
|
||||
Reasons = decision.Reasons.ToArray(),
|
||||
Rekor = rekor,
|
||||
Confidence = Math.Round(decision.Confidence, 6, MidpointRounding.AwayFromZero),
|
||||
Quieted = decision.Quieted,
|
||||
QuietedBy = decision.QuietedBy,
|
||||
Metadata = metadata,
|
||||
BuildIds = decision.BuildIds is { Count: > 0 } ? decision.BuildIds.ToArray() : null,
|
||||
Linksets = decision.Linksets is { Count: > 0 } ? decision.Linksets.ToArray() : null
|
||||
};
|
||||
}
|
||||
|
||||
return new RuntimePolicyResponseDto
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user