About custom-builtin-functions
A skill for extending the OPA/Rego policy engine with custom built-ins written in Go. It guides developers through implementation details such as namespacing, error handling, cancellation, and function documentation.
Key features
- 01Go custom built-in implementation
- 02chainloop.* namespace guidance
- 03Non-restrictive service call marking
- 04Context-aware timeout and cancellation
- 05Function signature documentation
Use cases
- 01Adding domain-specific functions to Rego policies
- 02Calling third-party services from policy functions
Install
Copy the command and run it in a terminal.
$
npx skills add https:/ / github.com/ chainloop-dev/ chainloop --skill custom-builtin-functionsAfter installing, type/custom-builtin-functionsin Claude Code to confirm it loaded.
Details
From the project READMEPolicy Engine Extension
The OPA/Rego policy engine supports custom built-in functions written in Go.
Adding Custom Built-ins:
- Create Built-in Implementation (e.g.,
pkg/policies/engine/rego/builtins/myfeature.go):
package builtins
import (
"github.com/open-policy-agent/opa/ast"
"github.com/open-policy-agent/opa/topdown"
"github.com/open-policy-agent/opa/types"
)
const myFuncName = "chainloop.my_function"
func RegisterMyBuiltins() error {
return Register(&ast.Builtin{
Name: myFuncName,
Description: "Description of what this function does",
Decl: types.NewFunction(
types.Args(types.Named("input", types.S).Description("this is the input")),
types.Named("result", types.S).Description("this is the result"),
),
}, myFunctionImpl)
}
func myFunctionImpl(bctx topdown.BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
// Extract arguments
input, ok := operands[0].Value.(ast.String)
if !ok {
return fmt.Errorf("input must be a string")
}
// Implement logic
result := processInput(string(input))
// Return result
return iter(ast.StringTerm(result))
}
// Autoregisters on package load
func init() {
if err := RegisterMyBuiltins(); err != nil {
panic(fmt.Sprintf("failed to register built-ins: %v", err))
}
}
- Use in Policies (
*.rego):
package example
import rego.v1
result := {
"violations": violations,
"skipped": false
}
violations contains msg if {
output := chainloop.my_function(input.value)
output != "expected"
msg := "Function returned unexpected value"
}
Guidelines:
- Use
chainloop.*namespace for all custom built-ins - Functions that call third party services should be marked as non-restrictive by adding the
NonRestrictiveBuiltincategory to the builtin definition - Always implement proper error handling and return meaningful error messages
- Use context from
BuiltinContextfor timeout/cancellation support - Document function signatures and behavior in the
Descriptionfield and parameter definitions
Comments
Markdown supported