Documentation
      ¶
    
    
  
    
  
    Overview ¶
Package rego exposes high level APIs for evaluating Rego policies.
Index ¶
- func Compiler(c *ast.Compiler) func(r *Rego)
 - func DisableInlining(paths []string) 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 ParsedModule(module *ast.Module) func(*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)
 - func UnsafeBuiltins(unsafeBuiltins map[string]struct{}) func(r *Rego)
 - type CompileContext
 - type CompileOption
 - type CompileResult
 - type Errors
 - type EvalContext
 - type EvalOption
 - func EvalDisableInlining(paths []ast.Ref) EvalOption
 - func EvalInput(input interface{}) EvalOption
 - func EvalInstrument(instrument bool) EvalOption
 - func EvalMetrics(metric metrics.Metrics) EvalOption
 - func EvalParsedInput(input ast.Value) EvalOption
 - func EvalParsedUnknowns(unknowns []*ast.Term) EvalOption
 - func EvalPartialNamespace(ns string) EvalOption
 - func EvalTracer(tracer topdown.Tracer) EvalOption
 - func EvalTransaction(txn storage.Transaction) EvalOption
 - func EvalUnknowns(unknowns []string) EvalOption
 
- type ExpressionValue
 - type Location
 - type PartialQueries
 - type PartialResult
 - type PrepareConfig
 - type PrepareOption
 - type PreparedEvalQuery
 - type PreparedPartialQuery
 - type Rego
 - func (r *Rego) Compile(ctx context.Context, opts ...CompileOption) (*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)
 - func (r *Rego) PrepareForEval(ctx context.Context, opts ...PrepareOption) (PreparedEvalQuery, error)
 - func (r *Rego) PrepareForPartial(ctx context.Context, opts ...PrepareOption) (PreparedPartialQuery, 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
 - Rego.PrepareForEval
 - Rego.PrepareForPartial
 
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DisableInlining ¶
DisableInlining adds a set of paths to exclude from partial evaluation inlining.
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 ParsedImports ¶
ParsedImports returns an argument that adds Rego imports to the query's context.
func ParsedInput ¶
ParsedInput returns an argument that sets the Rego input document.
func ParsedModule ¶
ParsedModule returns an argument that adds a parsed Rego module. If a string module with the same filename name is added, it will override the parsed module.
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 function to write a human-readable version of the trace to the writer w.
func Runtime ¶
Runtime returns an argument that sets the runtime data to provide to the evaluation engine.
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.
func UnsafeBuiltins ¶
UnsafeBuiltins is a helper that sets a set of unsafe builtins on the compiler.
If a rule or query is found to refer to an unsafe a built-in function, an error will be returned when the Rego object is executed.
Types ¶
type CompileContext ¶
type CompileContext struct {
	// contains filtered or unexported fields
}
    CompileContext contains options for Compile calls.
type CompileOption ¶
type CompileOption func(*CompileContext)
CompileOption defines a function to set options on Compile calls.
func CompilePartial ¶
func CompilePartial(yes bool) CompileOption
CompilePartial defines an option to control whether partial evaluation is run before the query is planned and compiled.
type CompileResult ¶
type CompileResult struct {
	Bytes []byte `json:"bytes"`
}
    CompileResult represents the 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.
type EvalContext ¶
type EvalContext struct {
	// contains filtered or unexported fields
}
    EvalContext defines the set of options allowed to be set at evaluation time. Any other options will need to be set on a new Rego object.
type EvalOption ¶
type EvalOption func(*EvalContext)
EvalOption defines a function to set an option on an EvalConfig
func EvalDisableInlining ¶
func EvalDisableInlining(paths []ast.Ref) EvalOption
EvalDisableInlining returns an argument that adds a set of paths to exclude from partial evaluation inlining.
func EvalInput ¶
func EvalInput(input interface{}) EvalOption
    EvalInput configures the input for a Prepared Query's evaluation
func EvalInstrument ¶
func EvalInstrument(instrument bool) EvalOption
EvalInstrument enables or disables instrumenting for a Prepared Query's evaluation
func EvalMetrics ¶
func EvalMetrics(metric metrics.Metrics) EvalOption
EvalMetrics configures the metrics for a Prepared Query's evaluation
func EvalParsedInput ¶
func EvalParsedInput(input ast.Value) EvalOption
EvalParsedInput configures the input for a Prepared Query's evaluation
func EvalParsedUnknowns ¶
func EvalParsedUnknowns(unknowns []*ast.Term) EvalOption
EvalParsedUnknowns returns an argument that sets the values to treat as unknown during partial evaluation.
func EvalPartialNamespace ¶
func EvalPartialNamespace(ns string) EvalOption
EvalPartialNamespace returns an argument that sets the namespace to use for partial evaluation results. The namespace must be a valid package path component.
func EvalTracer ¶
func EvalTracer(tracer topdown.Tracer) EvalOption
EvalTracer configures a tracer for a Prepared Query's evaluation
func EvalTransaction ¶
func EvalTransaction(txn storage.Transaction) EvalOption
EvalTransaction configures the Transaction for a Prepared Query's evaluation
func EvalUnknowns ¶
func EvalUnknowns(unknowns []string) EvalOption
EvalUnknowns returns an argument that sets the values to treat as unknown during partial evaluation.
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 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. If rego.Rego#Prepare was used to create the PartialResult this may lose the pre-parsed/compiled parts of the original Rego object. In those cases using rego.PartialResult#Eval is likely to be more performant.
type PrepareConfig ¶
type PrepareConfig struct {
	// contains filtered or unexported fields
}
    PrepareConfig holds settings to control the behavior of the Prepare call.
type PrepareOption ¶
type PrepareOption func(*PrepareConfig)
PrepareOption defines a function to set an option to control the behavior of the Prepare call.
func WithNoInline ¶
func WithNoInline(paths []string) PrepareOption
WithNoInline adds a set of paths to exclude from partial evaluation inlining.
func WithPartialEval ¶
func WithPartialEval() PrepareOption
WithPartialEval configures an option for PrepareForEval which will have it perform partial evaluation while preparing the query (similar to rego.Rego#PartialResult)
type PreparedEvalQuery ¶
type PreparedEvalQuery struct {
	// contains filtered or unexported fields
}
    PreparedEvalQuery holds the prepared Rego state that has been pre-processed for subsequent evaluations.
func (PreparedEvalQuery) Eval ¶
func (pq PreparedEvalQuery) Eval(ctx context.Context, options ...EvalOption) (ResultSet, error)
Eval evaluates this PartialResult's Rego object with additional eval options and returns a ResultSet. If options are provided they will override the original Rego options respective value. The original Rego object transaction will *not* be re-used. A new transaction will be opened if one is not provided with an EvalOption.
type PreparedPartialQuery ¶
type PreparedPartialQuery struct {
	// contains filtered or unexported fields
}
    PreparedPartialQuery holds the prepared Rego state that has been pre-processed for partial evaluations.
func (PreparedPartialQuery) Partial ¶
func (pq PreparedPartialQuery) Partial(ctx context.Context, options ...EvalOption) (*PartialQueries, error)
Partial runs partial evaluation on the prepared query and returns the result. The original Rego object transaction will *not* be re-used. A new transaction will be opened if one is not provided with an EvalOption.
type Rego ¶
type Rego struct {
	// contains filtered or unexported fields
}
    Rego constructs a query and can be evaluated to obtain results.
func (*Rego) Compile ¶
func (r *Rego) Compile(ctx context.Context, opts ...CompileOption) (*CompileResult, error)
Compile returns a compiled policy query.
func (*Rego) Eval ¶
Eval evaluates this Rego object and returns a ResultSet.
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)
}
Output: 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.
	}
}
Output: 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"])
}
Output: 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)
	}
}
Output: 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)
	}
}
Output: 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)
}
Output: 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)
}
Output: 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)
}
Output: 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)
}
Output: 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 {
		fmt.Println("error (after txn):", err)
	}
}
Output: value (inside txn): pepperoni value (outside txn): cheese error (after txn): storage_invalid_txn_error: stale transaction
func (*Rego) Partial ¶
func (r *Rego) Partial(ctx context.Context) (*PartialQueries, error)
Partial runs partial evaluation on r and returns the result.
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])
	}
}
Output: 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.
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)
		}
	}
}
Output: input 1 allowed: true input 2 allowed: false input 3 allowed: true
func (*Rego) PrepareForEval ¶
func (r *Rego) PrepareForEval(ctx context.Context, opts ...PrepareOption) (PreparedEvalQuery, error)
PrepareForEval will parse inputs, modules, and query arguments in preparation of evaluating them.
Example ¶
package main
import (
	"context"
	"fmt"
	"github.com/open-policy-agent/opa/rego"
)
func main() {
	ctx := context.Background()
	// Create a simple query
	r := rego.New(
		rego.Query("input.x == 1"),
	)
	// Prepare for evaluation
	pq, err := r.PrepareForEval(ctx)
	if err != nil {
		// Handle error.
	}
	// Raw input data that will be used in the first evaluation
	input := map[string]interface{}{"x": 2}
	// Run the evaluation
	rs, err := pq.Eval(ctx, rego.EvalInput(input))
	if err != nil {
		// Handle error.
	}
	// Inspect results.
	fmt.Println("initial result:", rs[0].Expressions[0])
	// Update input
	input["x"] = 1
	// Run the evaluation with new input
	rs, err = pq.Eval(ctx, rego.EvalInput(input))
	if err != nil {
		// Handle error.
	}
	// Inspect results.
	fmt.Println("updated result:", rs[0].Expressions[0])
}
Output: initial result: false updated result: true
func (*Rego) PrepareForPartial ¶
func (r *Rego) PrepareForPartial(ctx context.Context, opts ...PrepareOption) (PreparedPartialQuery, error)
PrepareForPartial will parse inputs, modules, and query arguments in preparation of partially evaluating them.
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.PrepareForPartial(ctx)
	if err != nil {
		// Handle error.
	}
	pqs, err := pq.Partial(ctx)
	if err != nil {
		// Handle error.
	}
	// Inspect result
	fmt.Println("First evaluation")
	for i := range pqs.Queries {
		fmt.Printf("Query #%d: %v\n", i+1, pqs.Queries[i])
	}
	// Evaluate with specified input
	exampleInput := map[string]string{
		"method": "GET",
	}
	// Evaluate again with different input and unknowns
	pqs, err = pq.Partial(ctx,
		rego.EvalInput(exampleInput),
		rego.EvalUnknowns([]string{"input.user", "input.is_admin", "input.path"}),
	)
	if err != nil {
		// Handle error.
	}
	// Inspect result
	fmt.Println("Second evaluation")
	for i := range pqs.Queries {
		fmt.Printf("Query #%d: %v\n", i+1, pqs.Queries[i])
	}
}
Output: First evaluation Query #1: "GET" = input.method; input.path = ["reviews", _]; input.is_admin Query #2: "GET" = input.method; input.path = ["reviews", user3]; user3 = input.user Second evaluation Query #1: input.path = ["reviews", _]; input.is_admin Query #2: input.path = ["reviews", user3]; user3 = input.user
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.