Everything You Need to Know About the Difference Between OPA's Rego and AWS Cedar
Tags: security, architecture, webdev
Published: 2023-07-20 07:41:35

---
title: Everything You Need to Know About the Difference Between OPA's Rego and AWS Cedar
published: true
date: 2023-07-20 07:42:00 UTC
tags: security, architecture, webdev
description: Thinking about implementing policy as code for authorization? This article will guide you through all the differences between Rego and Cedar, so you can make a smarter choice for your next project.
canonical_url: https://www.permit.io/blog/opa-vs-cedar
---

Policy as code (PAC) is a software development approach that treats authorization policies as code. This means that policies are written in a programming language, such as Rego or Cedar, and are stored in a version control system alongside the rest of the code. 

This blog discusses the benefits of PAC and dives deeper into the difference between two popular PAC languages: Rego, the language of [<u>Open Policy Engine (OPA)</u>](https://www.openpolicyagent.org/ "https://www.openpolicyagent.org/"), a CNCF project, and [<u>Cedar</u>](https://www.cedarpolicy.com/ "https://www.cedarpolicy.com/") - the language used by Amazon Verified Permissions (AVP), a service that provides fine-grained authorization for AWS resources.

## The benefits of using PAC:

- **Decoupling policy from code:** PAC allows you to decouple policy from code, which makes it easier to manage and update policies.

- **Increased flexibility:** PAC gives you more flexibility in how you define policies, allowing you to use a variety of programming constructs to create complex policies.

- **Improved performance:** PAC can improve performance by offloading policy evaluation from the application to a dedicated policy engine.

## What do Rego and Cedar have in common?

- Both are open-source.

- Both are policy as code.

- Both focus on decoupling policy from code.

- Both are general-purpose languages and decision engines.

- Both are focused on performance and auditability.

- Both enable low latency by running the policy engine at or close to the consuming service.

- Both are logical-programming languages.

- Both can be managed at scale with [<u>OPAL</u>](https://github.com/permitio/opal "https://github.com/permitio/opal").

## What are the key differences?

- <u><strong>Area of focus</strong></u>: OPA is a CNCF project, and is mostly used for infrastructure-level access control (service to service, admission control in K8s). Cedar is focused on application-level authorization.

- <u><strong>The language</strong></u>:   
Rego is a Datalog / Prolog derivative. While also a logical programming language, Cedar opts to be less generic in favor of a more domain-specific focus.

- <u><strong>Readability</strong></u>:   
Cedar is more readable than Rego. Cedar is more strictly typed, and has more focus on readability than Rego, with basic Cedar code more likely to be legible to a layman (Thanks to its clear opinionated structure), unlike Rego code which can be extremely complex to read.

- <u><strong>Tools and modules</strong></u>:   
Rego has many built-in tools that can be used to do things like parsing GraphQL, JSON Web Tokens, searching a JSON graph, and more. Currently, Cedar doesn’t include such built-in tools, aiming for more of a pure language model.

- <u><strong>Underlying frameworks</strong></u>:   
OPA and Rego are Go based, and natively support compilation to Web assembly, while Cedar is Rust based. These are not dramatic differences, but they can be relevant if you’re looking to embed or extend the languages with other Go, or Rust code.

- <u><strong>Community and ecosystem</strong></u>:   
OPA is a CNCF project, with a large community (though not very open - due to conflicts with Styra, the company behind OPA); Cedar has a [<u>small blooming community</u>](http://cedar-policy.slack.com/ "http://cedar-policy.slack.com/") and the backing of AWS - known for its power to create cloud-native standards single-handedly.

- <u><strong>Running and testing</strong></u>:   
Rego can be run as part of a Go SDK, CLI, as a daemon agent with OPA, and can be found embedded as a plugin in many common tools (e.g. Gatekeeper, Conftest, Envoy, Kong), Cedar can be run as a Rust SDK, CLI, and via Cedar-agent as a standalone daemon.

- <u><strong>Managing Data</strong></u>:   
Baseline Policy data is mapped easily in both engines as part of the code and is somewhat more structured in Cedar. Both engines also support loading dynamic data. Rego works with generic JSON documents mapped under top-level arguments `input` (for incoming requests) and `data`(in memory store). Cedar also uses JSON-like documents, which are referred to as “entity slices”, for input. These are automatically mapped into entities (i.e. principals, resources, and groups) - as such Cedar, unlike Rego, expects a specific format for the inputted JSON.  
  
In-memory / mem-cached data in Cedar is only supported as part of the Cedar agent.  
Both engines are supported by [<u>OPAL</u>](https://github.com/permitio/opal "https://github.com/permitio/opal") which can manage both engines with policy and data in realtime (And even run them side by side)

## Cedar / Rego Pros and Cons - A quick summary

### Rego

- Pros:

  - Widely used and supported

  - A mature ecosystem of tools and modules

  - Flexible and expressive language

- Cons:

  - Can be complex and difficult to learn

  - Not as readable as Cedar (especially for non-technical team members) 

- General:

  - More infrastructure and K8s oriented

### Cedar

- Pros:

  - More readable than Rego

  - More structured language

  - Backed by AWS

- Cons:

  - Currently, not as widely used or supported as Rego

  - A smaller ecosystem of tools and modules

- General:

  - More application permissions oriented 

## Let’s look at some code

Below is a simple RBAC+ownership (aka light ABAC)  in both languages.

### <u>Rego⁠</u>

```go
package play

import future.keywords.if

default allow := false
allow if permit(input.principal, input.action, input.resource)

permit("alice", "read", "document") if input.resource_owner == input.principal

```

### <u>Cedar</u>

```javascript
permit(
  principal == User::"alice", 
  action    == Action::"read", 
  resource  == Document::"document"
) when {
  resource.owner == principal
}
```

As you can see, the two policies are very similar, and both languages can be considered declarative. The main difference is that the Rego policy uses a more loose and generic syntax, while the Cedar policy uses a more strict syntax - which adds clarity for even non-technical readers (with its “permit / when, unless” structure, and keywords (e.g. principal, action, resource))

## Bottomline: Which one to choose?

In summary, Rego and Cedar are powerful policy-as-code languages and engines with distinct characteristics. While they share common features, such as being open-source, decoupling policy from code, and focusing on performance and auditability, they differ in their area of focus, language design, available tools and modules, and underlying infrastructure.

Both languages have a steep learning curve and complexity associated with them. To simplify the initial adoption process, tools like Permit.io can be useful. Permit.io offers a low-code UI solution to generate Rego or Cedar code, enabling developers (and nontechnical stakeholders) to get started more quickly and overcome the initial challenges of these languages.

Ultimately, the choice between Rego and Cedar depends on the specific use case and requirements, while using code generation tools can enable faster adoption and easier flexibility in switching or mixing the two. So perhaps you don’t have to choose.