@@ -61,6 +61,12 @@ type EvalSummaryDebugInfo struct {
6161}
6262
6363func Evaluate (opts * EvalOptions , logger zerolog.Logger ) (* EvalSummary , error ) {
64+ // Check if this is a generic policy evaluation
65+ if opts .MaterialPath == "" {
66+ return evaluateGeneric (opts , logger )
67+ }
68+
69+ // Material-based evaluation
6470 // 1. Craft material with annotations
6571 material , err := craftMaterial (opts .MaterialPath , opts .MaterialKind , & logger )
6672 if err != nil {
@@ -83,6 +89,38 @@ func Evaluate(opts *EvalOptions, logger zerolog.Logger) (*EvalSummary, error) {
8389 return summary , nil
8490}
8591
92+ func evaluateGeneric (opts * EvalOptions , logger zerolog.Logger ) (* EvalSummary , error ) {
93+ // Create policy attachment without material selector
94+ ref := opts .PolicyPath
95+ scheme , _ := policies .RefParts (opts .PolicyPath )
96+ if scheme == "" {
97+ // Default to file://
98+ ref = fmt .Sprintf ("file://%s" , opts .PolicyPath )
99+ }
100+
101+ attachment := & v1.PolicyAttachment {
102+ Policy : & v1.PolicyAttachment_Ref {Ref : ref },
103+ With : opts .Inputs ,
104+ }
105+
106+ // Create policy verifier
107+ verifierOpts := buildPolicyVerifierOptions (opts .AllowedHostnames , opts .Debug )
108+ pol := & v1.Policies {}
109+ v := policies .NewPolicyVerifier (pol , opts .AttestationClient , & logger , verifierOpts ... )
110+
111+ // Evaluate generic policy
112+ policyEv , err := v .EvaluateGeneric (context .Background (), attachment , nil )
113+ if err != nil {
114+ return nil , err
115+ }
116+
117+ if policyEv == nil {
118+ return nil , fmt .Errorf ("no execution branch matched, or all of them were ignored" )
119+ }
120+
121+ return buildEvalSummary (policyEv , opts .Debug ), nil
122+ }
123+
86124func createPolicies (policyPath string , inputs map [string ]string , materialID string ) (* v1.Policies , error ) {
87125 // Check if the policy path already has a scheme (chainloop://, http://, https://, file://)
88126 ref := policyPath
@@ -97,25 +135,14 @@ func createPolicies(policyPath string, inputs map[string]string, materialID stri
97135 {
98136 Policy : & v1.PolicyAttachment_Ref {Ref : ref },
99137 With : inputs ,
100- // Add selector to support generic policies
101- Selector : & v1.PolicyAttachment_MaterialSelector {
102- Name : materialID ,
103- },
104138 },
105139 },
106140 Attestation : nil ,
107141 }, nil
108142}
109143
110144func verifyMaterial (pol * v1.Policies , material * v12.Attestation_Material , materialPath string , debug bool , allowedHostnames []string , attestationClient controlplanev1.AttestationServiceClient , logger * zerolog.Logger ) (* EvalSummary , error ) {
111- var opts []policies.PolicyVerifierOption
112- if len (allowedHostnames ) > 0 {
113- opts = append (opts , policies .WithAllowedHostnames (allowedHostnames ... ))
114- }
115-
116- opts = append (opts , policies .WithIncludeRawData (debug ))
117- opts = append (opts , policies .WithEnablePrint (enablePrint ))
118-
145+ opts := buildPolicyVerifierOptions (allowedHostnames , debug )
119146 v := policies .NewPolicyVerifier (pol , attestationClient , logger , opts ... )
120147 policyEvs , err := v .VerifyMaterial (context .Background (), material , materialPath )
121148 if err != nil {
@@ -127,8 +154,22 @@ func verifyMaterial(pol *v1.Policies, material *v12.Attestation_Material, materi
127154 }
128155
129156 // Only one evaluation expected for a single policy attachment
130- policyEv := policyEvs [0 ]
157+ return buildEvalSummary (policyEvs [0 ], debug ), nil
158+ }
131159
160+ // buildPolicyVerifierOptions creates common policy verifier options
161+ func buildPolicyVerifierOptions (allowedHostnames []string , debug bool ) []policies.PolicyVerifierOption {
162+ var opts []policies.PolicyVerifierOption
163+ if len (allowedHostnames ) > 0 {
164+ opts = append (opts , policies .WithAllowedHostnames (allowedHostnames ... ))
165+ }
166+ opts = append (opts , policies .WithIncludeRawData (debug ))
167+ opts = append (opts , policies .WithEnablePrint (enablePrint ))
168+ return opts
169+ }
170+
171+ // buildEvalSummary converts a PolicyEvaluation to an EvalSummary
172+ func buildEvalSummary (policyEv * v12.PolicyEvaluation , debug bool ) * EvalSummary {
132173 summary := & EvalSummary {
133174 Result : & EvalResult {
134175 Skipped : policyEv .GetSkipped (),
@@ -153,7 +194,7 @@ func verifyMaterial(pol *v1.Policies, material *v12.Attestation_Material, materi
153194 if rr == nil {
154195 continue
155196 }
156- // Take the first input found, as we only allow one material input
197+ // Take the first input found
157198 if len (summary .DebugInfo .Inputs ) == 0 && rr .Input != nil {
158199 summary .DebugInfo .Inputs = append (summary .DebugInfo .Inputs , json .RawMessage (rr .Input ))
159200 }
@@ -164,7 +205,7 @@ func verifyMaterial(pol *v1.Policies, material *v12.Attestation_Material, materi
164205 }
165206 }
166207
167- return summary , nil
208+ return summary
168209}
169210
170211func craftMaterial (materialPath , materialKind string , logger * zerolog.Logger ) (* v12.Attestation_Material , error ) {
@@ -174,19 +215,6 @@ func craftMaterial(materialPath, materialKind string, logger *zerolog.Logger) (*
174215 Uploader : nil , // Skip uploads
175216 }
176217
177- // If no material path provided, create empty material
178- if materialPath == "" {
179- return & v12.Attestation_Material {
180- Id : "empty-input" ,
181- M : & v12.Attestation_Material_String_ {
182- String_ : & v12.Attestation_Material_KeyVal {
183- Id : "empty-input" ,
184- Value : "{}" ,
185- },
186- },
187- }, nil
188- }
189-
190218 // Explicit kind
191219 if materialKind != "" {
192220 kind , ok := v1 .CraftingSchema_Material_MaterialType_value [materialKind ]
0 commit comments