prep docs and service updates
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
This commit is contained in:
@@ -10,6 +10,11 @@ public static class ProjectionHashing
|
||||
private const string PolicyVersionProperty = nameof(FindingProjection.PolicyVersion);
|
||||
private const string StatusProperty = nameof(FindingProjection.Status);
|
||||
private const string SeverityProperty = nameof(FindingProjection.Severity);
|
||||
private const string RiskScoreProperty = nameof(FindingProjection.RiskScore);
|
||||
private const string RiskSeverityProperty = nameof(FindingProjection.RiskSeverity);
|
||||
private const string RiskProfileVersionProperty = nameof(FindingProjection.RiskProfileVersion);
|
||||
private const string RiskExplanationIdProperty = nameof(FindingProjection.RiskExplanationId);
|
||||
private const string RiskEventSequenceProperty = nameof(FindingProjection.RiskEventSequence);
|
||||
private const string LabelsProperty = nameof(FindingProjection.Labels);
|
||||
private const string CurrentEventIdProperty = nameof(FindingProjection.CurrentEventId);
|
||||
private const string ExplainRefProperty = nameof(FindingProjection.ExplainRef);
|
||||
@@ -27,6 +32,11 @@ public static class ProjectionHashing
|
||||
[PolicyVersionProperty] = projection.PolicyVersion,
|
||||
[StatusProperty] = projection.Status,
|
||||
[SeverityProperty] = projection.Severity,
|
||||
[RiskScoreProperty] = projection.RiskScore,
|
||||
[RiskSeverityProperty] = projection.RiskSeverity,
|
||||
[RiskProfileVersionProperty] = projection.RiskProfileVersion,
|
||||
[RiskExplanationIdProperty] = projection.RiskExplanationId?.ToString(),
|
||||
[RiskEventSequenceProperty] = projection.RiskEventSequence,
|
||||
[LabelsProperty] = projection.Labels.DeepClone(),
|
||||
[CurrentEventIdProperty] = projection.CurrentEventId.ToString(),
|
||||
[ExplainRefProperty] = projection.ExplainRef,
|
||||
|
||||
@@ -14,6 +14,11 @@ public interface IPolicyEvaluationService
|
||||
public sealed record PolicyEvaluationResult(
|
||||
string? Status,
|
||||
decimal? Severity,
|
||||
decimal? RiskScore,
|
||||
string? RiskSeverity,
|
||||
string? RiskProfileVersion,
|
||||
Guid? RiskExplanationId,
|
||||
long? RiskEventSequence,
|
||||
JsonObject Labels,
|
||||
string? ExplainRef,
|
||||
JsonArray Rationale);
|
||||
|
||||
@@ -42,6 +42,11 @@ public sealed class InlinePolicyEvaluationService : IPolicyEvaluationService
|
||||
var result = new PolicyEvaluationResult(
|
||||
status,
|
||||
severity,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
existingProjection?.RiskEventSequence,
|
||||
labels,
|
||||
explainRef,
|
||||
rationale);
|
||||
@@ -62,6 +67,11 @@ public sealed class InlinePolicyEvaluationService : IPolicyEvaluationService
|
||||
return new PolicyEvaluationResult(
|
||||
existingProjection?.Status,
|
||||
existingProjection?.Severity,
|
||||
existingProjection?.RiskScore,
|
||||
existingProjection?.RiskSeverity,
|
||||
existingProjection?.RiskProfileVersion,
|
||||
existingProjection?.RiskExplanationId,
|
||||
existingProjection?.RiskEventSequence,
|
||||
labels,
|
||||
existingProjection?.ExplainRef,
|
||||
rationale);
|
||||
|
||||
@@ -129,6 +129,10 @@ internal sealed class PolicyEngineEvaluationService : IPolicyEvaluationService
|
||||
{
|
||||
["status"] = existingProjection.Status,
|
||||
["severity"] = existingProjection.Severity,
|
||||
["riskScore"] = existingProjection.RiskScore,
|
||||
["riskSeverity"] = existingProjection.RiskSeverity,
|
||||
["riskProfileVersion"] = existingProjection.RiskProfileVersion,
|
||||
["riskExplanationId"] = existingProjection.RiskExplanationId?.ToString(),
|
||||
["labels"] = existingProjection.Labels.DeepClone(),
|
||||
["explainRef"] = existingProjection.ExplainRef,
|
||||
["rationale"] = existingProjection.PolicyRationale.DeepClone()
|
||||
@@ -168,6 +172,22 @@ internal sealed class PolicyEngineEvaluationService : IPolicyEvaluationService
|
||||
severity = decimalSeverity;
|
||||
}
|
||||
|
||||
decimal? riskScore = null;
|
||||
var riskScoreElement = item.GetPropertyOrDefault("riskScore");
|
||||
if (riskScoreElement.HasValue && riskScoreElement.Value.ValueKind == JsonValueKind.Number && riskScoreElement.Value.TryGetDecimal(out var decimalRiskScore))
|
||||
{
|
||||
riskScore = decimalRiskScore;
|
||||
}
|
||||
var riskSeverity = item.GetPropertyOrDefault("riskSeverity")?.GetString();
|
||||
var riskProfileVersion = item.GetPropertyOrDefault("riskProfileVersion")?.GetString();
|
||||
Guid? riskExplanationId = null;
|
||||
var riskExplanationElement = item.GetPropertyOrDefault("riskExplanationId");
|
||||
if (riskExplanationElement.HasValue && riskExplanationElement.Value.ValueKind == JsonValueKind.String &&
|
||||
Guid.TryParse(riskExplanationElement.Value.GetString(), out var parsedExplanation))
|
||||
{
|
||||
riskExplanationId = parsedExplanation;
|
||||
}
|
||||
|
||||
var labelsNode = new JsonObject();
|
||||
var labelsElement = item.GetPropertyOrDefault("labels");
|
||||
if (labelsElement.HasValue && labelsElement.Value.ValueKind == JsonValueKind.Object)
|
||||
@@ -175,6 +195,12 @@ internal sealed class PolicyEngineEvaluationService : IPolicyEvaluationService
|
||||
labelsNode = (JsonObject)labelsElement.Value.ToJsonNode()!;
|
||||
}
|
||||
var explainRef = item.GetPropertyOrDefault("explainRef")?.GetString();
|
||||
long? riskEventSequence = null;
|
||||
var riskEventSequenceElement = item.GetPropertyOrDefault("riskEventSequence");
|
||||
if (riskEventSequenceElement.HasValue && riskEventSequenceElement.Value.ValueKind == JsonValueKind.Number)
|
||||
{
|
||||
riskEventSequence = riskEventSequenceElement.Value.GetInt64();
|
||||
}
|
||||
|
||||
JsonArray rationale;
|
||||
var rationaleElement = item.GetPropertyOrDefault("rationale");
|
||||
@@ -191,7 +217,17 @@ internal sealed class PolicyEngineEvaluationService : IPolicyEvaluationService
|
||||
rationale = (JsonArray)rationaleElement.Value.ToJsonNode()!;
|
||||
}
|
||||
|
||||
return new PolicyEvaluationResult(status, severity, labelsNode, explainRef, rationale);
|
||||
return new PolicyEvaluationResult(
|
||||
status,
|
||||
severity,
|
||||
riskScore,
|
||||
riskSeverity,
|
||||
riskProfileVersion,
|
||||
riskExplanationId,
|
||||
riskEventSequence ?? record.SequenceNumber,
|
||||
labelsNode,
|
||||
explainRef,
|
||||
rationale);
|
||||
}
|
||||
|
||||
throw new InvalidOperationException("Policy engine response did not include evaluation for requested finding.");
|
||||
|
||||
@@ -66,6 +66,11 @@ internal sealed class PolicyEvaluationCache : IDisposable
|
||||
return new PolicyEvaluationResult(
|
||||
result.Status,
|
||||
result.Severity,
|
||||
result.RiskScore,
|
||||
result.RiskSeverity,
|
||||
result.RiskProfileVersion,
|
||||
result.RiskExplanationId,
|
||||
result.RiskEventSequence,
|
||||
labelsClone,
|
||||
result.ExplainRef,
|
||||
rationaleClone);
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
-- 004_ledger_attestations.sql
|
||||
-- LEDGER-OBS-54-001: storage for attestation verification exports
|
||||
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ledger_attestations (
|
||||
tenant_id text NOT NULL,
|
||||
attestation_id uuid NOT NULL,
|
||||
artifact_id text NOT NULL,
|
||||
finding_id text NULL,
|
||||
verification_status text NOT NULL,
|
||||
verification_time timestamptz NOT NULL,
|
||||
dsse_digest text NOT NULL,
|
||||
rekor_entry_id text NULL,
|
||||
evidence_bundle_ref text NULL,
|
||||
ledger_event_id uuid NOT NULL,
|
||||
recorded_at timestamptz NOT NULL,
|
||||
merkle_leaf_hash text NOT NULL,
|
||||
root_hash text NOT NULL,
|
||||
cycle_hash text NOT NULL,
|
||||
projection_version text NOT NULL
|
||||
);
|
||||
|
||||
ALTER TABLE ledger_attestations
|
||||
ADD CONSTRAINT pk_ledger_attestations PRIMARY KEY (tenant_id, attestation_id);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS ix_ledger_attestations_recorded
|
||||
ON ledger_attestations (tenant_id, recorded_at, attestation_id);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS ix_ledger_attestations_artifact
|
||||
ON ledger_attestations (tenant_id, artifact_id, recorded_at DESC);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS ix_ledger_attestations_finding
|
||||
ON ledger_attestations (tenant_id, finding_id, recorded_at DESC)
|
||||
WHERE finding_id IS NOT NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS ix_ledger_attestations_status
|
||||
ON ledger_attestations (tenant_id, verification_status, recorded_at DESC);
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,15 @@
|
||||
-- 004_risk_fields.sql
|
||||
-- Add risk scoring fields to findings_projection (LEDGER-RISK-66-001/002)
|
||||
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE findings_projection
|
||||
ADD COLUMN IF NOT EXISTS risk_score NUMERIC(6,3),
|
||||
ADD COLUMN IF NOT EXISTS risk_severity TEXT,
|
||||
ADD COLUMN IF NOT EXISTS risk_profile_version TEXT,
|
||||
ADD COLUMN IF NOT EXISTS risk_explanation_id UUID,
|
||||
ADD COLUMN IF NOT EXISTS risk_event_sequence BIGINT;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS ix_projection_risk ON findings_projection (tenant_id, risk_severity, risk_score DESC);
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,16 @@
|
||||
-- 005_risk_fields.sql
|
||||
-- LEDGER-RISK-66-001: add risk scoring fields to findings projection
|
||||
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE findings_projection
|
||||
ADD COLUMN IF NOT EXISTS risk_score numeric(6,2) NULL,
|
||||
ADD COLUMN IF NOT EXISTS risk_severity text NULL,
|
||||
ADD COLUMN IF NOT EXISTS risk_profile_version text NULL,
|
||||
ADD COLUMN IF NOT EXISTS risk_explanation_id text NULL,
|
||||
ADD COLUMN IF NOT EXISTS risk_event_sequence bigint NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS ix_findings_projection_risk
|
||||
ON findings_projection (tenant_id, risk_severity, risk_score DESC, recorded_at DESC);
|
||||
|
||||
COMMIT;
|
||||
@@ -460,6 +460,10 @@ internal sealed class NoOpPolicyEvaluationService : IPolicyEvaluationService
|
||||
return Task.FromResult(new PolicyEvaluationResult(
|
||||
Status: current?.Status ?? "new",
|
||||
Severity: current?.Severity,
|
||||
RiskScore: current?.RiskScore,
|
||||
RiskSeverity: current?.RiskSeverity,
|
||||
RiskProfileVersion: current?.RiskProfileVersion,
|
||||
RiskExplanationId: current?.RiskExplanationId,
|
||||
Labels: labels,
|
||||
ExplainRef: null,
|
||||
Rationale: new JsonArray()));
|
||||
|
||||
Reference in New Issue
Block a user