Skip to content

Commit c66211c

Browse files
committed
feat(policies): lenient structured finding validation at runtime
Make structured finding validation errors non-fatal during attestation crafting while keeping strict validation in policy development mode. When a policy returns malformed structured data at runtime, the violation is preserved as a plain string with FindingDegraded=true and a warning, instead of failing the entire evaluation. Add WithLenientFindingValidation() option to PolicyVerifier using the existing functional options pattern. The CLI policydevel path keeps strict validation (default) for fast feedback during policy authoring. Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>
1 parent 1041f32 commit c66211c

8 files changed

Lines changed: 246 additions & 60 deletions

File tree

app/controlplane/api/gen/frontend/attestation/v1/crafting_state.ts

Lines changed: 32 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.Violation.jsonschema.json

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.Violation.schema.json

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/attestation/crafter/api/attestation/v1/crafting_state.pb.go

Lines changed: 20 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/attestation/crafter/api/attestation/v1/crafting_state.proto

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,13 @@ message PolicyEvaluation {
284284
PolicySASTFinding sast = 4;
285285
PolicyLicenseViolationFinding license_violation = 5;
286286
}
287+
288+
// True when the policy declared a finding_type and returned structured data,
289+
// but validation failed at runtime. The violation was kept as a plain string
290+
// and the finding oneof is NOT set. Consumers should treat this as a
291+
// data-quality signal: the violation exists but structured finding data is
292+
// missing due to a policy authoring issue.
293+
bool finding_degraded = 6;
287294
}
288295

289296
message Reference {

pkg/attestation/crafter/crafter.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,7 @@ func (c *Crafter) addMaterial(ctx context.Context, m *schemaapi.CraftingSchema_M
706706
c.Logger,
707707
policies.WithAllowedHostnames(c.CraftingState.Attestation.PoliciesAllowedHostnames...),
708708
policies.WithDefaultGate(c.CraftingState.Attestation.GetBlockOnPolicyViolation()),
709+
policies.WithLenientFindingValidation(),
709710
)
710711
policyGroupResults, err := pgv.VerifyMaterial(ctx, mt, value)
711712
if err != nil {
@@ -723,6 +724,7 @@ func (c *Crafter) addMaterial(ctx context.Context, m *schemaapi.CraftingSchema_M
723724
c.Logger,
724725
policies.WithAllowedHostnames(c.CraftingState.Attestation.PoliciesAllowedHostnames...),
725726
policies.WithDefaultGate(c.CraftingState.Attestation.GetBlockOnPolicyViolation()),
727+
policies.WithLenientFindingValidation(),
726728
)
727729
policyResults, err := pv.VerifyMaterial(ctx, mt, value)
728730
if err != nil {
@@ -758,6 +760,7 @@ func (c *Crafter) EvaluateAttestationPolicies(ctx context.Context, attestationID
758760
policies.WithAllowedHostnames(c.CraftingState.Attestation.PoliciesAllowedHostnames...),
759761
policies.WithDefaultGate(c.CraftingState.Attestation.GetBlockOnPolicyViolation()),
760762
policies.WithEvalPhase(phase),
763+
policies.WithLenientFindingValidation(),
761764
)
762765
policyEvaluations, err := pv.VerifyStatement(ctx, statement)
763766
if err != nil {
@@ -768,6 +771,7 @@ func (c *Crafter) EvaluateAttestationPolicies(ctx context.Context, attestationID
768771
policies.WithAllowedHostnames(c.CraftingState.Attestation.PoliciesAllowedHostnames...),
769772
policies.WithDefaultGate(c.CraftingState.Attestation.GetBlockOnPolicyViolation()),
770773
policies.WithEvalPhase(phase),
774+
policies.WithLenientFindingValidation(),
771775
)
772776
policyGroupResults, err := pgv.VerifyStatement(ctx, statement)
773777
if err != nil {

0 commit comments

Comments
 (0)