Skip to content

Rego query utility based on OPA (Open Policy Agent)

License

Notifications You must be signed in to change notification settings

m-mizutani/opaq

Repository files navigation

opaq Go Reference test gosec trivy lint

Rego query library with local policy file or data based on OPA (Open Policy Agent). This library is a wrapper of Open Policy Agent and Rego to evaluate local policy files or data.

Install

go get github.com/m-mizutani/opaq

Basic Usage

Here is a basic example of how to use the library. The example code is in examples/basic.

package authz

allow if {
    input.user == "alice"
    input.action == "read"
}

And here is the example code.

package main

import (
    "context"
    "log"
    "fmt"

    "github.com/m-mizutani/opaq"
)

func main() {
    // Create a new client with policy files from a directory
    client, err := opaq.New(opaq.Files("./policy"))
    if err != nil {
        log.Fatal(err)
    }

    // Define input data
    input := map[string]any{
        "user": "alice",
        "action": "read",
        "resource": "document-123",
    }

    // Define output structure
    var output struct {
        Allow bool `json:"allow"`
    }

    // Query the policy
    err = client.Query(
        context.Background(),
        "data.authz",
        input,
        &output,
    )
    if err != nil {
        log.Fatal(err)
    }

    if output.Allow {
        fmt.Println("Access granted")
    } else {
        fmt.Println("Access denied")
    }
    // Output:
    // Access granted
}

Advanced Features

Custom Logger

opaq supports logger with slog package. This is useful when you want to see the debug logs from Rego policy. The example code is in examples/logger.

logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
    Level: slog.LevelDebug,
}))

// Create a new client with logger
client, err := opaq.New(
    opaq.Files("./policy"),
    opaq.WithLogger(logger),
)
if err != nil {
    log.Fatal(err)
}

It outputs the debug logs like below when the query is evaluated.

time=2025-02-20T05:07:11.280+09:00 level=DEBUG msg="Evaluating query" query_id=BDSXIVAWYU7YSZFKR2KYGI54HQ query=data.authz input="map[action:read resource:document-123 user:alice]"
time=2025-02-20T05:07:11.280+09:00 level=DEBUG msg="Query evaluated" query_id=BDSXIVAWYU7YSZFKR2KYGI54HQ result="[{Expressions:[map[allow:true]] Bindings:map[]}]"
time=2025-02-20T05:07:11.280+09:00 level=DEBUG msg="Unmarshaled result" query_id=BDSXIVAWYU7YSZFKR2KYGI54HQ output=&{Allow:true}

Print Hook

opaq supports print hook to show the print statements from Rego policy. The example code is in examples/print-hook.

	hook := func(ctx print.Context, msg string) error {
		fmt.Println("📣", msg) // Show print statements from Rego policy
		return nil
	}
	// Query the policy
	err = client.Query(
		context.Background(),
		"data.authz",
		input,
		&output,
		opaq.WithPrintHook(hook),
	)
	if err != nil {
		log.Fatal(err)
	}

And the policy should have print statement.

package authz

allow if {
    print("input", input)
    input.user == "alice"
    input.action == "read"
}

Then the output is like below.

📣 input {"action": "read", "resource": "document-123", "user": "alice"}

Rego Version Selection

import "github.com/open-policy-agent/opa/ast"

client, err := opaq.New(
    opaq.Files("./policies"),
    opaq.WithRegoVersion(ast.RegoV1),
)

Policy from data

opaq supports policy from data in Go code. This is useful when testing.

policy := `
package pkg1

allow if {
    input.user == "alice"
    input.action == "read"
}
`

client, err := opaq.New(
    opaq.Data("pkg1", policy),
)

Accessing Policy Metadata

opaq supports accessing policy metadata. The metadata is the annotations in the policy file. See official documentation for more details about Rego metadata.

// Get policy annotations
metadata := client.Metadata()

Accessing Policy Sources

opaq supports accessing policy sources. The sources are the policy files. Please note that the sources can not be changed after the client is created.

// Get policy sources
sources := client.Sources()

License

Apache License, Version 2.0

See LICENSE for more details.

About

Rego query utility based on OPA (Open Policy Agent)

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages