TAOS
← White Papers
AI Engineering

Why We Embedded Rego in Rust Instead of Calling OPA Over HTTP

May 1, 2026Taos Team
RegoRustArchitecture

Why We Embedded Rego in Rust Instead of Calling OPA Over HTTP

Category: AI Engineering | Reading time: 6 min


The Architecture Decision

When designing the Taos governance kernel, we faced an early decision: how should Rego policy be evaluated?

Option A: Run OPA as a sidecar or service, evaluate policies over HTTP. Option B: Embed a Rego engine directly in the Rust kernel.

We chose Option B — Regorus, an open-source Rego engine written in Rust. This post explains why.


The Performance Case

Policy evaluation in Taos fires on every workflow step that touches a governed action. In a high-throughput AP processing environment — 10,000 invoices per day — that's 50,000+ policy evaluations daily (five governed steps per workflow).

OPA over HTTP:

  • Network roundtrip: 1–5ms (loopback), 5–50ms (remote)
  • JSON serialisation/deserialisation: 0.1–0.5ms
  • OPA evaluation: 0.1–1ms
  • Total: 1–55ms per evaluation

Regorus embedded:

  • Function call (no network): 0ms
  • No serialisation needed (Rust struct to Rego input): ~0.01ms
  • Regorus evaluation: 0.05–0.2ms
  • Total: 0.05–0.2ms per evaluation

At 50,000 evaluations/day, the difference is roughly 25 seconds of total latency (Regorus) vs. 25 minutes (OPA HTTP, conservatively). At peak payment processing times, the latency difference is felt by every user waiting for a payment to process.


The Reliability Case

An OPA sidecar is an additional service. Additional services have additional failure modes:

  • OPA process crashes → kernel can't evaluate policy → payment system stops or bypasses controls
  • OPA container is OOM-killed → same problem
  • Network partition between kernel and OPA → same problem
  • OPA upgrade causes policy incompatibility → breaking change in production

With Regorus embedded in the kernel binary, the policy engine has exactly the same availability as the kernel itself. If the kernel is running, policy evaluation works. There is no additional service to operate, monitor, upgrade, or recover.

For a system that handles financial controls, eliminating an availability dependency is worth significant engineering investment.


The Security Case

An HTTP-accessible policy service creates an attack surface. If OPA is reachable over the network, it can potentially be:

  • Queried directly by attackers to understand what policies are in force
  • Targeted for DoS (slow down policy evaluation → slow down or bypass financial controls)
  • Manipulated if the OPA API has authentication weaknesses

Regorus embedded in the kernel has no external API surface. Policy evaluation is a function call inside the kernel process. There is no port to probe, no API to attack, no separate process to compromise.

The policy engine's security boundary is the kernel's security boundary.


The Consistency Case

The Taos kernel and the Python governance client (agent/shared/taos_client.py) both evaluate Rego policy. When the Python agent runs a policy check before calling the kernel, it uses regopy — the Python binding for Regorus. The kernel uses Regorus directly.

This means both are evaluating the same engine against the same policy file. The policy check in the Python agent is not a reimplementation or approximation — it's the same Regorus engine running in a different process binding.

If OPA were used for the kernel and regopy for the Python agent, you'd have two different Rego implementations with potentially different evaluation semantics. A rule that passes in one might fail in the other due to implementation differences.

With Regorus end-to-end, the evaluation is identical. The Python agent's policy check is a reliable pre-flight — not a guess.


What Regorus Is

Regorus is an open-source Rego policy engine written in Rust, maintained by Microsoft. It implements the OPA Rego specification and passes the OPA test suite for the supported language features.

Key properties:

  • Pure Rust — no external runtime dependencies, compiles to a single binary
  • Embeddable — designed to be used as a library, not a service
  • OPA-compatible — the same .rego files that work with OPA work with Regorus (for supported features)
  • Fast — microsecond-range evaluation for typical policy rules
  • Small — adds ~2MB to the binary size

The Python binding, regopy, wraps the Rust library with PyO3. The same engine, the same evaluation logic, accessible from Python.


The Trade-Offs

Embedding Regorus rather than using OPA isn't without costs:

OPA features not in Regorus: OPA's bundle API, decision logging, status endpoint, and data API are not available in Regorus. If you need OPA's management features, you need OPA. For the Taos kernel's use case — embedded policy evaluation with policies loaded from file — Regorus covers the full requirement.

OPA ecosystem tooling: The opa CLI, OPA Playground, and Rego test runner work with OPA's server model. Regorus doesn't have equivalent tooling (yet). We use the opa CLI for policy development and testing; only the evaluation runtime uses Regorus.

Policy debugging: OPA provides detailed evaluation traces for debugging. Regorus provides query results. For production policy debugging, we rely on the audit log's rule_fired field and structured policy logging.

For Taos's requirements, the performance, reliability, and security benefits outweigh these trade-offs decisively.


Live Policy Reload Without a Service Restart

One unexpected benefit of the embedded approach: live policy reload is trivial.

With OPA as a service, live reload requires pushing a new policy bundle to the OPA server and waiting for it to acknowledge the update. This involves OPA's bundle API, potentially a storage backend, and a lifecycle management concern.

With Regorus embedded, live reload is:

def _reload_engine_from_source(rego_source: str) -> None:
    engine = regopy.Interpreter()
    engine.add_module("vendor_payment", rego_source)
    # Atomic pointer swap (CPython GIL)
    _tc._rego_engine = engine
    _tc._regopy_mod = regopy

Load the new source, build a new interpreter, swap the pointer. The next policy evaluation uses the new rules. The old interpreter is garbage-collected. No service management required.


The Bottom Line

Choosing Regorus over OPA HTTP for the Taos governance kernel was the right call for our requirements: 50μs evaluation latency, zero additional service dependencies, no external attack surface, and consistent evaluation semantics across Rust and Python runtimes.

If you need OPA's management features (bundle API, decision logging, multi-tenant policy management), use OPA. If you need embedded, high-performance Rego evaluation in a Rust binary or Python process, Regorus is the better tool.

Policy evaluation is a hot path. Treat it like one.


Tags: Regorus, OPA, Rego, embedded policy engine, Rust, performance, AI governance architecture