package rego
import "github.com/open-policy-agent/opa/rego"
Package rego exposes high level APIs for evaluating Rego policies.
Index ¶
- func Compiler(c *ast.Compiler) func(r *Rego)
- func Dump(w io.Writer) func(r *Rego)
- func Imports(p []string) func(r *Rego)
- func Input(x interface{}) func(r *Rego)
- func Instrument(yes bool) func(r *Rego)
- func Metrics(m metrics.Metrics) func(r *Rego)
- func Module(filename, input string) func(r *Rego)
- func Package(p string) func(r *Rego)
- func ParsedImports(imp []*ast.Import) func(r *Rego)
- func ParsedInput(x ast.Value) func(r *Rego)
- func ParsedPackage(pkg *ast.Package) func(r *Rego)
- func ParsedQuery(q ast.Body) func(r *Rego)
- func ParsedUnknowns(unknowns []*ast.Term) func(r *Rego)
- func PartialNamespace(ns string) func(r *Rego)
- func PrintTrace(w io.Writer, r *Rego)
- func Query(q string) func(r *Rego)
- func Runtime(term *ast.Term) func(r *Rego)
- func Store(s storage.Store) func(r *Rego)
- func Trace(yes bool) func(r *Rego)
- func Tracer(t topdown.Tracer) func(r *Rego)
- func Transaction(txn storage.Transaction) func(r *Rego)
- func Unknowns(unknowns []string) func(r *Rego)
- type CompileResult
- type Errors
- type ExpressionValue
- type Location
- type PartialQueries
- type PartialResult
- type Rego
- func New(options ...func(*Rego)) *Rego
- func (r *Rego) Compile(ctx context.Context) (*CompileResult, error)
- func (r *Rego) Eval(ctx context.Context) (ResultSet, error)
- func (r *Rego) Partial(ctx context.Context) (*PartialQueries, error)
- func (r *Rego) PartialEval(ctx context.Context) (PartialResult, error)
- func (r *Rego) PartialResult(ctx context.Context) (PartialResult, error)
- type Result
- type ResultSet
- type Vars
Examples ¶
- Rego.Eval (Compiler)
- Rego.Eval (Errors)
- Rego.Eval (Input)
- Rego.Eval (MultipleBindings)
- Rego.Eval (MultipleDocuments)
- Rego.Eval (Simple)
- Rego.Eval (SingleDocument)
- Rego.Eval (Storage)
- Rego.Eval (Tracer)
- Rego.Eval (Transactions)
- Rego.Partial
- Rego.PartialResult
Functions ¶
func Compiler ¶
Compiler returns an argument that sets the Rego compiler.
func Dump ¶
Dump returns an argument that sets the writer to dump debugging information to.
func Imports ¶
Imports returns an argument that adds a Rego import to the query's context.
func Input ¶
func Input(x interface{}) func(r *Rego)
Input returns an argument that sets the Rego input document. Input should be a native Go value representing the input document.
func Instrument ¶
Instrument returns an argument that enables instrumentation for diagnosing performance issues.
func Metrics ¶
Metrics returns an argument that sets the metrics collection.
func Module ¶
Module returns an argument that adds a Rego module.
func Package ¶
Package returns an argument that sets the Rego package on the query's context.
func ParsedImports ¶
ParsedImports returns an argument that adds Rego imports to the query's context.
func ParsedInput ¶
ParsedInput returns an argument that set sthe Rego input document.
func ParsedPackage ¶
ParsedPackage returns an argument that sets the Rego package on the query's context.
func ParsedQuery ¶
ParsedQuery returns an argument that sets the Rego query.
func ParsedUnknowns ¶
ParsedUnknowns returns an argument that sets the values to treat as unknown during partial evaluation.
func PartialNamespace ¶
PartialNamespace returns an argument that sets the namespace to use for partial evaluation results. The namespace must be a valid package path component.
func PrintTrace ¶
PrintTrace is a helper fnuction to write a human-readable version of the trace to the writer w.
func Query ¶
Query returns an argument that sets the Rego query.
func Runtime ¶
Runtime returns an argument that sets the runtime data to provide to the evaluation engine.
func Store ¶
Store returns an argument that sets the policy engine's data storage layer.
func Trace ¶
Trace returns an argument that enables tracing on r.
func Tracer ¶
Tracer returns an argument that adds a query tracer to r.
func Transaction ¶
func Transaction(txn storage.Transaction) func(r *Rego)
Transaction returns an argument that sets the transaction to use for storage layer operations.
func Unknowns ¶
Unknowns returns an argument that sets the values to treat as unknown during partial evaluation.
Types ¶
type CompileResult ¶
type CompileResult struct { Bytes []byte `json:"bytes"` }
CompileResult represents sthe result of compiling a Rego query, zero or more Rego modules, and arbitrary contextual data into an executable.
type Errors ¶
type Errors []error
Errors represents a collection of errors returned when evaluating Rego.
func (Errors) Error ¶
type ExpressionValue ¶
type ExpressionValue struct { Value interface{} `json:"value"` Text string `json:"text"` Location *Location `json:"location"` }
ExpressionValue defines the value of an expression in a Rego query.
func (*ExpressionValue) String ¶
func (ev *ExpressionValue) String() string
type Location ¶
Location defines a position in a Rego query or module.
type PartialQueries ¶
type PartialQueries struct { Queries []ast.Body `json:"queries,omitempty"` Support []*ast.Module `json:"modules,omitempty"` }
PartialQueries contains the queries and support modules produced by partial evaluation.
type PartialResult ¶
type PartialResult struct {
// contains filtered or unexported fields
}
PartialResult represents the result of partial evaluation. The result can be used to generate a new query that can be run when inputs are known.
func (PartialResult) Rego ¶
func (pr PartialResult) Rego(options ...func(*Rego)) *Rego
Rego returns an object that can be evaluated to produce a query result.
type Rego ¶
type Rego struct {
// contains filtered or unexported fields
}
Rego constructs a query and can be evaluated to obtain results.
func New ¶
New returns a new Rego object.
func (*Rego) Compile ¶
func (r *Rego) Compile(ctx context.Context) (*CompileResult, error)
Compile returnss a compiled policy query.
func (*Rego) Eval ¶
Eval evaluates this Rego object and returns a ResultSet.
Code:play
Output: Code:play
Output: Code:play
Output: Code:play
Output: Code:play
Output: Code:play
Output: Code:play
Output: Code:play
Output: Code:play
Output: Code:play
Output:Example (Compiler)¶
package main
import (
"context"
"fmt"
"github.com/open-policy-agent/opa/ast"
"github.com/open-policy-agent/opa/rego"
)
func main() {
ctx := context.Background()
// Define a simple policy.
module := `
package example
default allow = false
allow {
input.identity = "admin"
}
allow {
input.method = "GET"
}
`
// Compile the module. The keys are used as identifiers in error messages.
compiler, err := ast.CompileModules(map[string]string{
"example.rego": module,
})
// Create a new query that uses the compiled policy from above.
rego := rego.New(
rego.Query("data.example.allow"),
rego.Compiler(compiler),
rego.Input(
map[string]interface{}{
"identity": "bob",
"method": "GET",
},
),
)
// Run evaluation.
rs, err := rego.Eval(ctx)
if err != nil {
// Handle error.
}
// Inspect results.
fmt.Println("len:", len(rs))
fmt.Println("value:", rs[0].Expressions[0].Value)
}
len: 1
value: true
Example (Errors)¶
package main
import (
"context"
"fmt"
"github.com/open-policy-agent/opa/ast"
"github.com/open-policy-agent/opa/rego"
)
func main() {
ctx := context.Background()
r := rego.New(
rego.Query("data.example.p"),
rego.Module("example_error.rego",
`package example
p = true { not q[x] }
q = {1, 2, 3} { true }`,
))
_, err := r.Eval(ctx)
switch err := err.(type) {
case rego.Errors:
for i := range err {
switch e := err[i].(type) {
case *ast.Error:
fmt.Println("code:", e.Code)
fmt.Println("row:", e.Location.Row)
fmt.Println("filename:", e.Location.File)
}
}
default:
// Some other error occurred.
}
}
code: rego_unsafe_var_error
row: 3
filename: example_error.rego
Example (Input)¶
package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
"github.com/open-policy-agent/opa/rego"
)
func main() {
ctx := context.Background()
// Raw input data that will be used in evaluation.
raw := `{"users": [{"id": "bob"}, {"id": "alice"}]}`
d := json.NewDecoder(bytes.NewBufferString(raw))
// Numeric values must be represented using json.Number.
d.UseNumber()
var input interface{}
if err := d.Decode(&input); err != nil {
panic(err)
}
// Create a simple query over the input.
rego := rego.New(
rego.Query("input.users[idx].id = user_id"),
rego.Input(input))
//Run evaluation.
rs, err := rego.Eval(ctx)
if err != nil {
// Handle error.
}
// Inspect results.
fmt.Println("len:", len(rs))
fmt.Println("bindings.idx:", rs[1].Bindings["idx"])
fmt.Println("bindings.user_id:", rs[1].Bindings["user_id"])
}
len: 2
bindings.idx: 1
bindings.user_id: alice
Example (MultipleBindings)¶
package main
import (
"context"
"fmt"
"github.com/open-policy-agent/opa/rego"
)
func main() {
ctx := context.Background()
// Create query that produces multiple bindings for variable.
rego := rego.New(
rego.Query(`a = ["ex", "am", "ple"]; x = a[_]; not p[x]`),
rego.Package(`example`),
rego.Module("example.rego", `package example
p["am"] { true }
`),
)
// Run evaluation.
rs, err := rego.Eval(ctx)
// Inspect results.
fmt.Println("len:", len(rs))
fmt.Println("err:", err)
for i := range rs {
fmt.Printf("bindings[\"x\"]: %v (i=%d)\n", rs[i].Bindings["x"], i)
}
}
len: 2
err: <nil>
bindings["x"]: ex (i=0)
bindings["x"]: ple (i=1)
Example (MultipleDocuments)¶
package main
import (
"context"
"fmt"
"github.com/open-policy-agent/opa/rego"
)
func main() {
ctx := context.Background()
// Create query that produces multiple documents.
rego := rego.New(
rego.Query("data.example.p[x]"),
rego.Module("example.rego",
`package example
p = {"hello": "alice", "goodbye": "bob"} { true }`,
))
// Run evaluation.
rs, err := rego.Eval(ctx)
// Inspect results.
fmt.Println("len:", len(rs))
fmt.Println("err:", err)
for i := range rs {
fmt.Printf("bindings[\"x\"]: %v (i=%d)\n", rs[i].Bindings["x"], i)
fmt.Printf("value: %v (i=%d)\n", rs[i].Expressions[0].Value, i)
}
}
len: 2
err: <nil>
bindings["x"]: hello (i=0)
value: alice (i=0)
bindings["x"]: goodbye (i=1)
value: bob (i=1)
Example (Simple)¶
package main
import (
"context"
"fmt"
"github.com/open-policy-agent/opa/rego"
)
func main() {
ctx := context.Background()
// Create very simple query that binds a single variable.
rego := rego.New(rego.Query("x = 1"))
// Run evaluation.
rs, err := rego.Eval(ctx)
// Inspect results.
fmt.Println("len:", len(rs))
fmt.Println("bindings:", rs[0].Bindings)
fmt.Println("err:", err)
}
len: 1
bindings: map[x:1]
err: <nil>
Example (SingleDocument)¶
package main
import (
"context"
"fmt"
"github.com/open-policy-agent/opa/rego"
)
func main() {
ctx := context.Background()
// Create query that produces a single document.
rego := rego.New(
rego.Query("data.example.p"),
rego.Module("example.rego",
`package example
p = ["hello", "world"] { true }`,
))
// Run evaluation.
rs, err := rego.Eval(ctx)
// Inspect result.
fmt.Println("value:", rs[0].Expressions[0].Value)
fmt.Println("err:", err)
}
value: [hello world]
err: <nil>
Example (Storage)¶
package main
import (
"context"
"fmt"
"github.com/open-policy-agent/opa/rego"
"github.com/open-policy-agent/opa/storage/inmem"
"github.com/open-policy-agent/opa/util"
)
func main() {
ctx := context.Background()
data := `{
"example": {
"users": [
{
"name": "alice",
"likes": ["dogs", "clouds"]
},
{
"name": "bob",
"likes": ["pizza", "cats"]
}
]
}
}`
var json map[string]interface{}
err := util.UnmarshalJSON([]byte(data), &json)
if err != nil {
// Handle error.
}
// Manually create the storage layer. inmem.NewFromObject returns an
// in-memory store containing the supplied data.
store := inmem.NewFromObject(json)
// Create new query that returns the value
rego := rego.New(
rego.Query("data.example.users[0].likes"),
rego.Store(store))
// Run evaluation.
rs, err := rego.Eval(ctx)
if err != nil {
// Handle error.
}
// Inspect the result.
fmt.Println("value:", rs[0].Expressions[0].Value)
}
value: [dogs clouds]
Example (Tracer)¶
package main
import (
"context"
"os"
"github.com/open-policy-agent/opa/rego"
"github.com/open-policy-agent/opa/topdown"
)
func main() {
ctx := context.Background()
buf := topdown.NewBufferTracer()
// Create very simple query that binds a single variable, and enables tracing.
rego := rego.New(
rego.Query("x = 1"),
rego.Tracer(buf),
)
// Run evaluation.
rego.Eval(ctx)
// Inspect results.
topdown.PrettyTrace(os.Stdout, *buf)
}
Enter x = 1
| Eval x = 1
| Exit x = 1
Redo x = 1
| Redo x = 1
Example (Transactions)¶
package main
import (
"bytes"
"context"
"fmt"
"github.com/open-policy-agent/opa/rego"
"github.com/open-policy-agent/opa/storage"
"github.com/open-policy-agent/opa/storage/inmem"
)
func main() {
ctx := context.Background()
// Create storage layer and load dummy data.
store := inmem.NewFromReader(bytes.NewBufferString(`{
"favourites": {
"pizza": "cheese",
"colour": "violet"
}
}`))
// Open a write transaction on the store that will perform write operations.
txn, err := store.NewTransaction(ctx, storage.WriteParams)
if err != nil {
// Handle error.
}
// Create rego query that uses the transaction created above.
inside := rego.New(
rego.Query("data.favourites.pizza"),
rego.Store(store),
rego.Transaction(txn),
)
// Create rego query that DOES NOT use the transaction created above. Under
// the hood, the rego package will create it's own read-only transaction to
// ensure it evaluates over a consistent snapshot of the storage layer.
outside := rego.New(
rego.Query("data.favourites.pizza"),
rego.Store(store),
)
// Write change to storage layer inside the transaction.
err = store.Write(ctx, txn, storage.AddOp, storage.MustParsePath("/favourites/pizza"), "pepperoni")
if err != nil {
// Handle error.
}
// Run evaluation INSIDE the transction.
rs, err := inside.Eval(ctx)
if err != nil {
// Handle error.
}
fmt.Println("value (inside txn):", rs[0].Expressions[0].Value)
// Run evaluation OUTSIDE the transaction.
rs, err = outside.Eval(ctx)
if err != nil {
// Handle error.
}
fmt.Println("value (outside txn):", rs[0].Expressions[0].Value)
if err := store.Commit(ctx, txn); err != nil {
// Handle error.
}
// Run evaluation AFTER the transaction commits.
rs, err = outside.Eval(ctx)
if err != nil {
// Handle error.
}
fmt.Println("value (after txn):", rs[0].Expressions[0].Value)
}
value (inside txn): pepperoni
value (outside txn): cheese
value (after txn): pepperoni
func (*Rego) Partial ¶
func (r *Rego) Partial(ctx context.Context) (*PartialQueries, error)
Partial runs partial evaluation on r and returns the result.
Code:play
Output:Example¶
package main
import (
"context"
"fmt"
"github.com/open-policy-agent/opa/rego"
)
func main() {
ctx := context.Background()
// Define a simple policy for example purposes.
module := `package test
allow {
input.method = read_methods[_]
input.path = ["reviews", user]
input.user = user
}
allow {
input.method = read_methods[_]
input.path = ["reviews", _]
input.is_admin
}
read_methods = ["GET"]
`
r := rego.New(rego.Query("data.test.allow == true"), rego.Module("example.rego", module))
pq, err := r.Partial(ctx)
if err != nil {
// Handle error.
}
// Inspect result.
for i := range pq.Queries {
fmt.Printf("Query #%d: %v\n", i+1, pq.Queries[i])
}
}
Query #1: "GET" = input.method; input.path = ["reviews", _]; input.is_admin
Query #2: "GET" = input.method; input.path = ["reviews", user3]; user3 = input.user
func (*Rego) PartialEval ¶
func (r *Rego) PartialEval(ctx context.Context) (PartialResult, error)
PartialEval has been deprecated and renamed to PartialResult.
func (*Rego) PartialResult ¶
func (r *Rego) PartialResult(ctx context.Context) (PartialResult, error)
PartialResult partially evaluates this Rego object and returns a PartialResult.
Code:play
Output:Example¶
package main
import (
"bytes"
"context"
"fmt"
"github.com/open-policy-agent/opa/rego"
"github.com/open-policy-agent/opa/storage/inmem"
)
func main() {
ctx := context.Background()
// Define a role-based access control (RBAC) policy that decides whether to
// allow or deny requests. Requests are allowed if the user is bound to a
// role that grants permission to perform the operation on the resource.
module := `
package example
import data.bindings
import data.roles
default allow = false
allow {
user_has_role[role_name]
role_has_permission[role_name]
}
user_has_role[role_name] {
b = bindings[_]
b.role = role_name
b.user = input.subject.user
}
role_has_permission[role_name] {
r = roles[_]
r.name = role_name
match_with_wildcard(r.operations, input.operation)
match_with_wildcard(r.resources, input.resource)
}
match_with_wildcard(allowed, value) {
allowed[_] = "*"
}
match_with_wildcard(allowed, value) {
allowed[_] = value
}
`
// Define dummy roles and role bindings for the example. In real-world
// scenarios, this data would be pushed or pulled into the service
// embedding OPA either from an external API or configuration file.
store := inmem.NewFromReader(bytes.NewBufferString(`{
"roles": [
{
"resources": ["documentA", "documentB"],
"operations": ["read"],
"name": "analyst"
},
{
"resources": ["*"],
"operations": ["*"],
"name": "admin"
}
],
"bindings": [
{
"user": "bob",
"role": "admin"
},
{
"user": "alice",
"role": "analyst"
}
]
}`))
// Prepare and run partial evaluation on the query. The result of partial
// evaluation can be cached for performance. When the data or policy
// change, partial evaluation should be re-run.
r := rego.New(
rego.Query("data.example.allow"),
rego.Module("example.rego", module),
rego.Store(store),
)
pr, err := r.PartialEval(ctx)
if err != nil {
// Handle error.
}
// Define example inputs (representing requests) that will be used to test
// the policy.
examples := []map[string]interface{}{
{
"resource": "documentA",
"operation": "write",
"subject": map[string]interface{}{
"user": "bob",
},
},
{
"resource": "documentB",
"operation": "write",
"subject": map[string]interface{}{
"user": "alice",
},
},
{
"resource": "documentB",
"operation": "read",
"subject": map[string]interface{}{
"user": "alice",
},
},
}
for i := range examples {
// Prepare and run normal evaluation from the result of partial
// evaluation.
r := pr.Rego(
rego.Input(examples[i]),
)
rs, err := r.Eval(ctx)
if err != nil || len(rs) != 1 || len(rs[0].Expressions) != 1 {
// Handle erorr.
} else {
fmt.Printf("input %d allowed: %v\n", i+1, rs[0].Expressions[0].Value)
}
}
}
input 1 allowed: true
input 2 allowed: false
input 3 allowed: true
type Result ¶
type Result struct { Expressions []*ExpressionValue `json:"expressions"` Bindings Vars `json:"bindings,omitempty"` }
Result defines the output of Rego evaluation.
type ResultSet ¶
type ResultSet []Result
ResultSet represents a collection of output from Rego evaluation. An empty result set represents an undefined query.
type Vars ¶
type Vars map[string]interface{}
Vars represents a collection of variable bindings. The keys are the variable names and the values are the binding values.
func (Vars) WithoutWildcards ¶
WithoutWildcards returns a copy of v with wildcard variables removed.
Source Files ¶
- Version
- v0.10.6
- Published
- Mar 26, 2019
- Platform
- js/wasm
- Imports
- 15 packages
- Last checked
- 2 minutes ago –
Tools for package owners.