Skip to main content

OPA vs Enterprise OPA

Objective

Explain the differences between open-source OPA and Enterprise OPA (EOPA), name the main enterprise features and what each one solves, and explain why your Rego and your tests do not change when you move from one to the other.

Concept

Enterprise OPA (the eopa binary) is a drop-in compatible PDP: it speaks the same REST API, evaluates the same Rego, and loads the same bundles as open-source OPA. The policy you wrote and tested in this course runs on eopa unchanged. What EOPA adds is around the policy, for deployments that operate OPA at large scale or under stricter data-handling requirements. The four features to know:

Decision-log masking

OPA can emit a decision log: a record of each authorization decision, its input, and its result, for audit and replay. In production that input often carries sensitive fields (tokens, personal data, request bodies). EOPA can mask or drop configured fields from decision logs before they leave the PDP, so you keep an audit trail without exporting secrets. This is a data-governance control on the log pipeline, not a change to the decision.

Delta bundles

A normal bundle is a full snapshot; every update re-ships all data. When the data set is large and changes often, that is wasteful. Delta bundles send only the changes (the diff) since the last revision, so the PDP applies a small update instead of reloading everything. The result is faster propagation and less bandwidth for large, frequently changing data.

Datasources

Plain OPA gets its data from bundles it pulls on an interval, so data is only as fresh as the last bundle. EOPA datasources let the PDP pull data directly from live systems (for example HTTP endpoints, Kafka, LDAP, or SQL) into the data document, so policies can decide on near-real-time data without waiting for a bundle rebuild. You still write the same Rego against data; the datasource just keeps that data current.

Scale and performance

EOPA is built for high-throughput, low-latency evaluation: it is engineered to use less memory and to evaluate faster than OPA under heavy load, which matters when a single PDP fleet serves very high decision volume. The policy semantics are identical; the engine is tuned for the workload.

Why the policy does not change

All four features sit at the edges of policy evaluation: how logs are handled, how bundles are delivered, where data comes from, how fast the engine runs. The Rego contract (input in, decision out, default deny) is the same. That is the point of drop-in compatibility: you develop and test on opa, and adopt eopa when a deployment needs masking, delta bundles, live datasources, or the extra scale, without rewriting policy.

A control plane sits above both. EnforceAuth's Writ governs and deploys signed bundles across OPA and Enterprise OPA PDPs (Git-sourced bundles, dev to staging to prod promotion, decision logs and replay). Writ is the governance layer; it is not a PDP on the request path. The PDP is always OPA or Enterprise OPA.

Hands-on lab

No new Rego for this lesson. Confirm the compatibility claim by reasoning about the lab you already have:

  1. The lab's account_tiers allow list is data. Which EOPA feature would let that list be pulled live from an external system instead of shipped in a bundle? What stays the same in policy.rego?
  2. Suppose the decision log for this policy recorded input.subject.account, and that value is considered sensitive. Which EOPA feature addresses that, and does it change the allow or deny result?
  3. Re-run the same suite you would run on opa, and confirm nothing about the tests is EOPA-specific:
git clone https://github.com/EnforceAuth/university-labs.git
cd university-labs
opa test courses/opa-eopa-fundamentals -v

Check for understanding

  1. Match each EOPA feature to the problem it solves: decision-log masking, delta bundles, datasources, scale.
  2. True or false: adopting Enterprise OPA requires rewriting your Rego policies. Explain.
  3. Writ deploys bundles to OPA and Enterprise OPA PDPs. Is Writ itself a PDP on the request path? What component makes the runtime decision?