11//
2- // Copyright 2024 The Chainloop Authors.
2+ // Copyright 2024-2025 The Chainloop Authors.
33//
44// Licensed under the Apache License, Version 2.0 (the "License");
55// you may not use this file except in compliance with the License.
@@ -45,17 +45,20 @@ type AttestationStatus struct {
4545}
4646
4747type AttestationStatusResult struct {
48- AttestationID string `json:"attestationID"`
49- InitializedAt * time.Time `json:"initializedAt"`
50- WorkflowMeta * AttestationStatusWorkflowMeta `json:"workflowMeta"`
51- Materials []AttestationStatusResultMaterial `json:"materials"`
52- EnvVars map [string ]string `json:"envVars"`
53- RunnerContext * AttestationResultRunnerContext `json:"runnerContext"`
54- DryRun bool `json:"dryRun"`
55- Annotations []* Annotation `json:"annotations"`
56- IsPushed bool `json:"isPushed"`
57- PolicyEvaluations map [string ][]* PolicyEvaluation `json:"policy_evaluations,omitempty"`
58- HasPolicyViolations bool `json:"hasPolicyViolations"`
48+ AttestationID string `json:"attestationID"`
49+ InitializedAt * time.Time `json:"initializedAt"`
50+ WorkflowMeta * AttestationStatusWorkflowMeta `json:"workflowMeta"`
51+ Materials []AttestationStatusResultMaterial `json:"materials"`
52+ EnvVars map [string ]string `json:"envVars"`
53+ RunnerContext * AttestationResultRunnerContext `json:"runnerContext"`
54+ DryRun bool `json:"dryRun"`
55+ Annotations []* Annotation `json:"annotations"`
56+ IsPushed bool `json:"isPushed"`
57+ PolicyEvaluations map [string ][]* PolicyEvaluation `json:"policy_evaluations,omitempty"`
58+ HasPolicyViolations bool `json:"has_policy_violations"`
59+ MustBlockOnPolicyViolations bool `json:"must_block_on_policy_violations"`
60+ // This might only be set if the attestation is pushed
61+ Digest string `json:"digest"`
5962}
6063
6164type AttestationResultRunnerContext struct {
@@ -126,10 +129,11 @@ func (action *AttestationStatus) Run(ctx context.Context, attestationID string,
126129 ContractRevision : workflowMeta .GetSchemaRevision (),
127130 ContractName : workflowMeta .GetContractName (),
128131 },
129- InitializedAt : toTimePtr (att .InitializedAt .AsTime ()),
130- DryRun : c .CraftingState .DryRun ,
131- Annotations : pbAnnotationsToAction (c .CraftingState .InputSchema .GetAnnotations ()),
132- IsPushed : action .isPushed ,
132+ InitializedAt : toTimePtr (att .InitializedAt .AsTime ()),
133+ DryRun : c .CraftingState .DryRun ,
134+ Annotations : pbAnnotationsToAction (c .CraftingState .InputSchema .GetAnnotations ()),
135+ IsPushed : action .isPushed ,
136+ MustBlockOnPolicyViolations : att .GetBlockOnPolicyViolation (),
133137 }
134138
135139 if ! action .skipPolicyEvaluation {
@@ -146,12 +150,10 @@ func (action *AttestationStatus) Run(ctx context.Context, attestationID string,
146150 return nil , fmt .Errorf ("rendering statement: %w" , err )
147151 }
148152
149- res .PolicyEvaluations , err = action .getPolicyEvaluations (ctx , c , attestationID , statement )
153+ res .PolicyEvaluations , res . HasPolicyViolations , err = action .getPolicyEvaluations (ctx , c , attestationID , statement )
150154 if err != nil {
151155 return nil , fmt .Errorf ("getting policy evaluations: %w" , err )
152156 }
153-
154- res .HasPolicyViolations = len (res .PolicyEvaluations ) > 0
155157 }
156158
157159 if v := workflowMeta .GetVersion (); v != nil {
@@ -200,14 +202,15 @@ func (action *AttestationStatus) Run(ctx context.Context, attestationID string,
200202 return res , nil
201203}
202204
203- // getPolicyEvaluations retrieves both material-level and attestation-level policy evaluations
204- func (action * AttestationStatus ) getPolicyEvaluations (ctx context.Context , c * crafter.Crafter , attestationID string , statement * intoto.Statement ) (map [string ][]* PolicyEvaluation , error ) {
205+ // getPolicyEvaluations retrieves both material-level and attestation-level policy evaluations and returns if it has violations
206+ func (action * AttestationStatus ) getPolicyEvaluations (ctx context.Context , c * crafter.Crafter , attestationID string , statement * intoto.Statement ) (map [string ][]* PolicyEvaluation , bool , error ) {
205207 // grouped by material name
206208 evaluations := make (map [string ][]* PolicyEvaluation )
209+ var hasViolations bool
207210
208211 // Add attestation-level policy evaluations
209212 if err := c .EvaluateAttestationPolicies (ctx , attestationID , statement ); err != nil {
210- return nil , fmt .Errorf ("evaluating attestation policies: %w" , err )
213+ return nil , false , fmt .Errorf ("evaluating attestation policies: %w" , err )
211214 }
212215
213216 // map evaluations
@@ -217,14 +220,18 @@ func (action *AttestationStatus) getPolicyEvaluations(ctx context.Context, c *cr
217220 keyName = chainloop .AttPolicyEvaluation
218221 }
219222
223+ if len (v .GetViolations ()) > 0 {
224+ hasViolations = true
225+ }
226+
220227 if existing , ok := evaluations [keyName ]; ok {
221228 evaluations [keyName ] = append (existing , policyEvaluationStateToActionForStatus (v ))
222229 } else {
223230 evaluations [keyName ] = []* PolicyEvaluation {policyEvaluationStateToActionForStatus (v )}
224231 }
225232 }
226233
227- return evaluations , nil
234+ return evaluations , hasViolations , nil
228235}
229236
230237// populateMaterials populates the materials in the attestation result regardless of where they are defined
0 commit comments