OPA vs Cedar: policy engines compared for application authorisation

Open Policy Agent (Rego) vs Cedar: language design, analysis, performance and where each fits, from Kubernetes admission to app permissions.

Short answer

OPA is a general purpose policy engine: Rego can evaluate any JSON and return any shape of answer, which makes it the standard for infrastructure policy such as Kubernetes admission, Terraform checks and service mesh authorisation. Cedar is purpose-built for application authorisation: principal, action, resource, with permit and forbid rules, a schema and formal analysis. Pick Cedar for fine-grained permissions inside your product, OPA for guardrails across your platform. Using both in one organisation is normal.

OPACedar
OriginStyra, CNCF graduated projectAWS, open source since 2023
LanguageRego, Datalog-inspired, general purposeCedar, authorisation-specific
InputArbitrary JSON input and data documentsPrincipal, action, resource, context, entities
OutputAny JSON: booleans, lists of violations, objectsAllow or deny plus the policies that decided it
Conflict ruleWhatever you write; default value if undefinedDefault deny; any forbid overrides any permit
SchemaOptional (JSON Schema annotations)Schema validation built in
AnalysisTests, coverage, partial evaluationValidation, formal verification, SMT-based policy analysis
ImplementationGo, library or daemon, Wasm compile targetRust core, bindings for other languages
DistributionBundles and decision logsYour own store or Amazon Verified Permissions
Sweet spotKubernetes, CI, Envoy, cloud guardrailsIn-app RBAC, ABAC and hierarchy permissions

01How each one works

OPA evaluates Rego rules against an input document (the request) and a data document (loaded facts). Rules are queries: a rule is true if all its expressions hold for some binding of variables, and you can generate sets, objects and messages. OPA has no built-in notion of users or resources; you model everything. Since OPA 1.0, Rego v1 syntax with if and contains is the default.

Cedar evaluates permit and forbid policies over a request of principal, action, resource and context, plus an entity store with attributes and parent relationships. The language is deliberately limited (no loops, no arbitrary recursion) so it always terminates, can be validated against a schema, and can be analysed to answer questions such as whether two policy sets allow the same requests.

iExpressiveness vs analysability

Rego can express almost anything, which is why it fits infrastructure policy. Cedar gives up generality to gain predictability, which is what you want for permissions you must prove correct.

02The same policy in both

Rule: a user can view a document they own or one from their department, but nobody can view an archived document.

OPA (Rego v1)rego
package docs.authz

default allow := false

allow if {
	input.action == "view"
	not input.resource.archived
	input.resource.owner == input.principal.id
}

allow if {
	input.action == "view"
	not input.resource.archived
	input.resource.department == input.principal.department
}
Cedartext
permit (
  principal,
  action == Action::"view",
  resource is Document
)
when { resource.owner == principal };

permit (
  principal is User,
  action == Action::"view",
  resource is Document
)
when { resource.department == principal.department };

forbid (principal, action, resource is Document)
when { resource.archived };

Note the difference in how the exception is expressed. In Rego the archived check has to be repeated in every allow rule, or factored into a helper. In Cedar a single forbid overrides every permit, so a new permit added later cannot accidentally reopen archived documents.

03When to pick which

  • Kubernetes admission, Terraform plans, CI config checks or Envoy ext_authz: OPA, with Gatekeeper or conftest. The ecosystem is there and the output is often a list of violations, not a yes or no.
  • Fine-grained permissions in your own application, especially multi-tenant SaaS: Cedar. The principal, action, resource model and forbid-wins semantics match the problem.
  • You need to prove properties of policy changes, such as a refactor allowing nothing new: Cedar's analysis tooling is built for this.
  • Large relationship graphs (Google Docs style sharing at scale): neither alone. Cedar needs the relevant entities passed in with each request; consider a Zanzibar-style ReBAC system and use Cedar or OPA for the attribute rules on top.
  • Data filtering (which rows can this user see): OPA partial evaluation can compile policy into query conditions; Cedar's equivalent is less mature.

04Common mistakes and migration notes

  • Rego: writing rules that are undefined rather than false and forgetting a default. Always set default allow := false.
  • Rego: mixing pre-1.0 syntax (no if, no contains) with OPA 1.x. Run opa fmt and opa check, or the rego.v1 import on older versions.
  • Cedar: expecting policies to fetch data. Cedar evaluates only the entities you supply, so your app must load the principal, resource and their parents first.
  • Both: putting the engine on the network path for every request without caching or a local sidecar. Authorisation latency adds to every call.
  • Migrating Rego to Cedar: translate deny rules into forbid policies and let them stand alone, rather than folding conditions into every permit.
!Decision logging

Whichever engine you choose, log the inputs and decision for every evaluation (with secrets redacted). Without decision logs you cannot answer who could access what, which is the first question in an incident.

05How to say it in an interview

“How to say it in the room

"OPA is a general engine: Rego over any JSON, any output, which is why it owns Kubernetes admission and infrastructure guardrails. Cedar is narrow on purpose: principal, action, resource, default deny and forbid wins, with schema validation and formal analysis. I'd use Cedar for product permissions where I need to prove a change is safe, and OPA for platform policy."

Questions people ask

Q1Is Cedar faster than OPA?+

For simple authorisation checks both evaluate in microseconds to low milliseconds. Cedar's restricted language makes its performance more predictable; OPA's speed depends heavily on how the Rego is written and how much data is loaded.

Q2Can Cedar be used outside AWS?+

Yes. Cedar is open source under Apache 2.0 with a Rust implementation and language bindings, and runs anywhere. Amazon Verified Permissions is a managed service built on it.

Q3Can OPA do RBAC and ABAC?+

Yes. Roles, attributes and relationships are just data and input documents in OPA. You write the logic yourself, which is flexible but means more to test.

Q4What is Rego v1?+

The syntax made default in OPA 1.0 (December 2024). It requires the if keyword for rule bodies and contains for multi-value rules, removing ambiguities in the older syntax.

Q5Should I use OPA Gatekeeper or Kyverno instead?+

For Kubernetes only, Kyverno uses YAML policies and is easier for many teams; Gatekeeper uses Rego and shares skills with the rest of OPA. Cedar is not a Kubernetes admission tool.

Go deeper

Terms on this page