@@ -24,6 +24,7 @@ import (
2424 "github.com/chainloop-dev/chainloop/pkg/policies/engine"
2525 "github.com/open-policy-agent/opa/ast"
2626 "github.com/open-policy-agent/opa/rego"
27+ "github.com/open-policy-agent/opa/v1/topdown/print"
2728 "golang.org/x/exp/maps"
2829)
2930
@@ -37,6 +38,8 @@ type Engine struct {
3738 allowedNetworkDomains []string
3839 // includeRawData determines whether to collect raw evaluation data
3940 includeRawData bool
41+ // enablePrint determines whether to enable print statements in rego policies
42+ enablePrint bool
4043}
4144
4245type EngineOption func (* newEngineOptions )
@@ -59,10 +62,17 @@ func WithIncludeRawData(include bool) EngineOption {
5962 }
6063}
6164
65+ func WithEnablePrint (enable bool ) EngineOption {
66+ return func (e * newEngineOptions ) {
67+ e .enablePrint = enable
68+ }
69+ }
70+
6271type newEngineOptions struct {
6372 operatingMode EnvironmentMode
6473 allowedNetworkDomains []string
6574 includeRawData bool
75+ enablePrint bool
6676}
6777
6878// NewEngine creates a new policy engine with the given options
@@ -88,6 +98,7 @@ func NewEngine(opts ...EngineOption) *Engine {
8898 // append base allowed network domains to the user provided ones
8999 allowedNetworkDomains : append (baseAllowedNetworkDomains , options .allowedNetworkDomains ... ),
90100 includeRawData : options .includeRawData ,
101+ enablePrint : options .enablePrint ,
91102 }
92103}
93104
@@ -112,6 +123,15 @@ var builtinFuncNotAllowed = []*ast.Builtin{
112123 ast .Trace ,
113124}
114125
126+ // Implements the OPA print.Hook interface to capture and output
127+ // print statements from Rego policies during evaluation.
128+ type regoOutputHook struct {}
129+
130+ func (p * regoOutputHook ) Print (_ print.Context , msg string ) error { //nolint:forbidigo
131+ fmt .Println (msg )
132+ return nil
133+ }
134+
115135// Force interface
116136var _ engine.PolicyEngine = (* Engine )(nil )
117137
@@ -156,11 +176,21 @@ func (r *Engine) Verify(ctx context.Context, policy *engine.Policy, input []byte
156176 var res rego.ResultSet
157177 // Function to execute the query with appropriate parameters
158178 executeQuery := func (rule string , strict bool ) error {
179+ options := []func (r * rego.Rego ){regoInput , regoFunc , rego .Capabilities (r .Capabilities ())}
180+
181+ // Add print support if enabled
182+ if r .enablePrint {
183+ options = append (options ,
184+ rego .EnablePrintStatements (true ),
185+ rego .PrintHook (& regoOutputHook {}),
186+ )
187+ }
188+
159189 if strict {
160- res , err = queryRego (ctx , rule , regoInput , regoFunc , rego .Capabilities (r .Capabilities ()), rego .StrictBuiltinErrors (true ))
161- } else {
162- res , err = queryRego (ctx , rule , regoInput , regoFunc , rego .Capabilities (r .Capabilities ()))
190+ options = append (options , rego .StrictBuiltinErrors (true ))
163191 }
192+
193+ res , err = queryRego (ctx , rule , options ... )
164194 return err
165195 }
166196
0 commit comments