Architecture
Big picture
OPA is one Go binary made of layered packages. The CLI in cmd/ bundles subcommands under a cobra root (cmd/commands.go:14), and main.go:22 runs cmd.RootCommand.Execute(). Below the CLI sit four layers that do the real work: v1/ast/ parses and compiles Rego, v1/topdown/ evaluates it, v1/rego/ orchestrates compile-then-evaluate as a high-level API, and v1/server/ exposes that as a REST policy decision point. Storage of external data is abstracted behind v1/storage/, and policy plus data are packaged for distribution by v1/bundle/.
Components
CLI (cmd/)
Subcommands such as eval, run, test, build, fmt, check, bench, and exec are registered on the cobra root RootCommand (cmd/commands.go:14). opa run --server starts the long-running PDP; the other commands are one-shot tools over the same evaluation core.
AST and compiler (v1/ast/)
This package holds the Rego parser, compiler, and type checker, across parser.go, compile.go, term.go, and policy.go. It turns Rego source text into a compiled, type-checked AST that the evaluator consumes.
Evaluation engine (v1/topdown/)
The evaluator runs top-down evaluation with unification. The main loop lives in eval.go and query.go, and the built-in functions (http.go, crypto.go, glob.go, and many more) live in the same directory. This is where a query is actually computed against input and data.
High-level API (v1/rego/)
v1/rego/rego.go is the orchestration layer. rego.New(...).Eval() ties together parse, compile, and evaluate. Both the server and embedded library users enter the engine through this package.
REST server (v1/server/)
The server is the PDP. v1DataGet (v1/server/server.go:1512) and v1DataPost (v1/server/server.go:1741) handle the default decision path /v1/data/<path>, evaluating the named rule against the request's input and returning JSON.
Storage and bundles (v1/storage/, v1/bundle/)
v1/storage/ defines the Store interface (v1/storage/interface.go:20) for base documents (external data), with an in-memory implementation included. v1/bundle/ handles loading, signing, and verifying bundles, the distribution unit that packages policy plus data and is pulled over HTTP or OCI.
How a request flows
A policy decision over HTTP runs as follows.
- A client sends
GETorPOSTto/v1/data/<path>, handled byv1DataGet(v1/server/server.go:1512) orv1DataPost(v1/server/server.go:1741). - The handler turns the request
inputinto an AST value and evaluates the named query through theregoAPI. (*Rego).Eval(v1/rego/rego.go:1502) opens a transaction and callsPrepareForEval(v1/rego/rego.go:1788), which parses and compiles the policy once.(*Rego).eval(v1/rego/rego.go:2309) builds atopdownquery for the default rego target and runs it.(*Query).Iter(v1/topdown/query.go:565) drives the evaluation loop in(*eval).eval(v1/topdown/eval.go:404), and the result is serialized back to JSON.
Embedded library users hit the same path: they call rego.New(...).Eval() directly rather than going through the server.
Key design decisions
The most consequential layout decision is the v1 shim. The root packages rego/, ast/, and topdown/ are not the implementation; they re-export v1/* through type aliases. For example rego/rego.go declares type Rego = v1.Rego and type EvalContext = v1.EvalContext against github.com/open-policy-agent/opa/v1/rego. This let OPA 1.0 switch Rego's default language from v0 to v1 without breaking existing import paths: callers keep importing github.com/open-policy-agent/opa/rego while new code consolidates under v1/.
A second decision is the separation between policy and data behind the Store interface (v1/storage/interface.go:20). External base documents are read through transactions, keeping the evaluation of policy distinct from the data it reads.
Extension points
- Built-in functions live alongside the evaluator in
v1/topdown/and the engine accepts custom built-ins through theregoAPI. v1/plugins/provides plugins for decision logging, bundle download, and status reporting.v1/sdk/is the embeddable SDK for running OPA inside another Go program.wasm/,v1/ir/, andv1/compile/compile Rego to WASM and an intermediate representation as alternative evaluation targets.