Skip to content

Commit a720e2a

Browse files
committed
refactor to use opa registry directly
Signed-off-by: Jose I. Paris <jiparis@chainloop.dev>
1 parent 479a242 commit a720e2a

7 files changed

Lines changed: 47 additions & 471 deletions

File tree

pkg/policies/engine/rego/builtins/errors.go

Lines changed: 0 additions & 31 deletions
This file was deleted.

pkg/policies/engine/rego/builtins/example.go

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,16 @@ import (
2727
const helloBuiltinName = "chainloop.hello"
2828

2929
func RegisterHelloBuiltin() error {
30-
return Register(&BuiltinDef{
31-
Name: helloBuiltinName,
32-
Decl: &ast.Builtin{
33-
Name: helloBuiltinName,
34-
Decl: types.NewFunction(
35-
types.Args(
36-
types.Named("name", types.S), // Digest to fetch
37-
),
38-
types.Named("response", types.A), // Response as object
30+
return Register(&ast.Builtin{
31+
Name: helloBuiltinName,
32+
Description: "Example builtin",
33+
Decl: types.NewFunction(
34+
types.Args(
35+
types.Named("name", types.S).Description("Name of the person to greet"), // Digest to fetch
3936
),
40-
},
41-
Impl: getHelloImpl,
42-
SecurityLevel: SecurityLevelPermissive, // Only available in permissive mode
43-
Description: "Example builtin",
44-
})
37+
types.Named("response", types.A).Description("the hello world message"), // Response as object
38+
),
39+
}, getHelloImpl)
4540
}
4641

4742
type helloResponse struct {
@@ -63,9 +58,3 @@ func getHelloImpl(_ topdown.BuiltinContext, operands []*ast.Term, iter func(*ast
6358
// call the iterator with the output value
6459
return iter(ast.NewTerm(ast.MustInterfaceToValue(helloResponse{message})))
6560
}
66-
67-
func init() {
68-
if err := RegisterHelloBuiltin(); err != nil {
69-
panic(fmt.Sprintf("failed to register Hello builtin: %v", err))
70-
}
71-
}

pkg/policies/engine/rego/builtins/example_test.go

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,7 @@ result := chainloop.hello("world")`,
4545

4646
for _, tt := range tests {
4747
t.Run(tt.name, func(t *testing.T) {
48-
// Create registry with HTTP built-ins
49-
registry := NewRegistry()
5048
require.NoError(t, RegisterHelloBuiltin())
51-
52-
// Get the built-in and add it to a new registry
53-
helloBuiltin, ok := Get(helloBuiltinName)
54-
require.True(t, ok)
55-
require.NoError(t, registry.Register(helloBuiltin))
56-
57-
// Register globally (permissive mode)
58-
require.NoError(t, registry.RegisterGlobal(true))
59-
6049
// Prepare rego evaluation
6150
ctx := context.Background()
6251
r := rego.New(

pkg/policies/engine/rego/builtins/registry.go

Lines changed: 8 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
package builtins
1616

1717
import (
18-
"sync"
19-
2018
"github.com/open-policy-agent/opa/v1/ast"
2119
"github.com/open-policy-agent/opa/v1/topdown"
2220
)
@@ -25,155 +23,17 @@ import (
2523
type SecurityLevel int
2624

2725
const (
28-
// SecurityLevelPermissive functions are only available in permissive (development) mode
29-
// These functions may make external calls, modify state, or perform operations
30-
// that are not suitable for production policy evaluation
31-
SecurityLevelPermissive SecurityLevel = iota
32-
33-
// SecurityLevelRestrictive functions are safe to use in restrictive (production) mode
34-
// These functions should be read-only, deterministic, and not make external calls
35-
// or access sensitive resources
36-
SecurityLevelRestrictive
26+
// NonRestrictiveBuiltin is used in builtin definition categories to mark a builtin as non-suitable for Chainloop's restrictive mode
27+
NonRestrictiveBuiltin = "non-restrictive"
3728
)
3829

39-
// BuiltinDef defines a custom built-in function that can be registered with OPA
40-
type BuiltinDef struct {
41-
// Name is the fully qualified name of the built-in (e.g., "chainloop.http_with_auth")
42-
Name string
43-
44-
// Decl is the built-in declaration that defines the function signature
45-
Decl *ast.Builtin
46-
47-
// Impl is the actual function implementation
48-
Impl topdown.BuiltinFunc
49-
50-
// SecurityLevel defines when this function is allowed to execute
51-
SecurityLevel SecurityLevel
52-
53-
// Description provides documentation for the function
54-
Description string
55-
}
56-
57-
// Registry manages custom built-in functions for the OPA policy engine
58-
type Registry struct {
59-
mu sync.RWMutex
60-
builtins map[string]*BuiltinDef
61-
}
62-
63-
// NewRegistry creates a new built-in function registry
64-
func NewRegistry() *Registry {
65-
return &Registry{
66-
builtins: make(map[string]*BuiltinDef),
67-
}
68-
}
69-
70-
// Register adds a built-in function to the registry
71-
func (r *Registry) Register(def *BuiltinDef) error {
72-
if def == nil {
73-
return ErrNilBuiltinDef
74-
}
75-
if def.Name == "" {
76-
return ErrEmptyBuiltinName
77-
}
78-
if def.Decl == nil {
79-
return ErrNilBuiltinDecl
80-
}
81-
if def.Impl == nil {
82-
return ErrNilBuiltinImpl
83-
}
84-
85-
r.mu.Lock()
86-
defer r.mu.Unlock()
87-
88-
r.builtins[def.Name] = def
89-
return nil
90-
}
91-
92-
// GetByMode returns all built-in functions that are allowed in the specified security level
93-
// Functions with SecurityLevelRestrictive are available in both modes
94-
func (r *Registry) GetByMode(isPermissive bool) []*BuiltinDef {
95-
r.mu.RLock()
96-
defer r.mu.RUnlock()
97-
98-
var result []*BuiltinDef
99-
for _, def := range r.builtins {
100-
// Restrictive functions are always available
101-
if def.SecurityLevel == SecurityLevelRestrictive {
102-
result = append(result, def)
103-
continue
104-
}
105-
106-
// Permissive functions only available in permissive mode
107-
if isPermissive && def.SecurityLevel == SecurityLevelPermissive {
108-
result = append(result, def)
109-
}
110-
}
111-
112-
return result
113-
}
114-
115-
// Get returns a built-in function by name
116-
func (r *Registry) Get(name string) (*BuiltinDef, bool) {
117-
r.mu.RLock()
118-
defer r.mu.RUnlock()
119-
120-
def, ok := r.builtins[name]
121-
return def, ok
122-
}
123-
124-
// All returns all registered built-in functions
125-
func (r *Registry) All() []*BuiltinDef {
126-
r.mu.RLock()
127-
defer r.mu.RUnlock()
128-
129-
result := make([]*BuiltinDef, 0, len(r.builtins))
130-
for _, def := range r.builtins {
131-
result = append(result, def)
132-
}
133-
134-
return result
135-
}
136-
137-
// RegisterGlobal registers built-ins globally with OPA based on security mode
30+
// Register registers built-ins globally with OPA
13831
// This should be called once during initialization
139-
func (r *Registry) RegisterGlobal(isPermissive bool) error {
140-
defs := r.GetByMode(isPermissive)
141-
142-
for _, def := range defs {
143-
// Register the built-in declaration with AST
144-
ast.RegisterBuiltin(def.Decl)
145-
146-
// Register the implementation with topdown
147-
topdown.RegisterBuiltinFunc(def.Name, def.Impl)
148-
}
32+
func Register(def *ast.Builtin, builtinFunc topdown.BuiltinFunc) error {
33+
// Register the built-in declaration with AST
34+
ast.RegisterBuiltin(def)
14935

36+
// Register the implementation with topdown
37+
topdown.RegisterBuiltinFunc(def.Name, builtinFunc)
15038
return nil
15139
}
152-
153-
// Global registry instance for default built-ins
154-
var globalRegistry = NewRegistry()
155-
156-
// Register adds a built-in to the global registry
157-
func Register(def *BuiltinDef) error {
158-
return globalRegistry.Register(def)
159-
}
160-
161-
// GetByMode returns built-ins from the global registry by mode
162-
func GetByMode(isPermissive bool) []*BuiltinDef {
163-
return globalRegistry.GetByMode(isPermissive)
164-
}
165-
166-
// Get returns a built-in from the global registry by name
167-
func Get(name string) (*BuiltinDef, bool) {
168-
return globalRegistry.Get(name)
169-
}
170-
171-
// All returns all built-ins from the global registry
172-
func All() []*BuiltinDef {
173-
return globalRegistry.All()
174-
}
175-
176-
// RegisterGlobalBuiltins registers global registry built-ins with OPA
177-
func RegisterGlobalBuiltins(isPermissive bool) error {
178-
return globalRegistry.RegisterGlobal(isPermissive)
179-
}

0 commit comments

Comments
 (0)