How to Write Your First Rules in Rego, the Policy Language for OPA

4 min read

What is Rego? 

Rego is the purpose-built declarative policy language that supports Open Policy Agent (OPA). It’s used to write policy that is easy to read and easy to write. Fundamentally, Rego inspects and transforms data in structured documents, allowing OPA to make policy decisions. Rego was originally inspired by Datalog, a common query language with a decades-long history, but extends its capabilities to support structured document models like JSON. 

Rego queries, put simply, ask questions of data stored in OPA. Rego policies then evaluate whether data complies with, or violates, the expected state of a system — that is how policy decisions are returned. For instance, a policy in Rego might declare, “Containers may never run in privileged mode.” If a request comes to OPA to run a container in privileged mode, that request is denied. Another policy, this time related to application entitlements, might say, “Only users in the Development group who control more than $500K in budget are allowed to access Service A.” If Alice, who is in the Dev group and controls more than $1M in budget, requests access to service A, that request is allowed. This is the simple power of policy as code expressed with Rego. 

Why should I use Rego?

Policy as code, via OPA, has become the de facto standard for authorization across the cloud-native stack. Meanwhile, policy as code is more valuable than ever, and will continue to become more so as more enterprises shift to the cloud. Master Rego and the power of policy as code is at your fingertips. 

Rego focuses on providing powerful support for referencing nested documents and ensuring that queries are correct and unambiguous. Rego is a declarative language, meaning policy authors can focus on what they want a query to return rather than how queries should be executed. These queries are simpler and more concise than the equivalent in an imperative language. 

As with any programming language, Rego can take some getting used to. Still, as Rego is purpose-built for authorization, users often find that Rego is the best and clearest way to express policy policy as code. Rego was designed to create policies that are, after an initial learning period, easy to read and write. While not known for being easy to author, as most coding languages have their challenges, this ease comes from uniformity. With OPA, once you learn to write Rego, you’ll never need another language for authorization again. To this end, there are several resources, including the Styra Academy and a vibrant community, to get users quickly up and running.

Using Rego, users can effectively make policy decisions on data fed to their OPA instances — enabling them to enforce authorization through policy as code.

How do I start using Rego?

In the simplest terms, Rego can be used by downloading OPA through a CLI and running commands. However, to understand Rego, one must understand the principles behind its design, and how those principles make Rego particularly well suited for describing policy:

1. Syntax should reflect real-world policies

2. Embrace hierarchical data

3. Optimize performance automatically

With these principles in mind, you can understand the core value of Rego: to embrace, in full, policy as code.

Rego makes its policy decisions by evaluating query inputs against policies and data. Therefore, to express policy you need to write expressions in Rego against that policy and other stored data. A number of expressions can be used in rego, and are joined by several built-in operators, such as ; (and) and := (assignment). A rule in Rego may then take the following form:

A user could then reference this rule in any number of useful ways, such as checking if a value containing a certain property exists in the set public_network, as we will learn to do further on.

What rules can I enforce with Rego?

To produce policy decisions in Rego, you write expressions against input and other data, such as temporary variables. True to its role as an authorization toolkit, OPA includes a set of built-in functions you can use to perform common operations like string manipulation, regular expression matching, arithmetic, aggregation and more. The simplest rule is a single expression and is defined in terms of a scalar (single) value, as opposed to a set. Every rule consists of a head and a body. In Rego, we say the rule head is true if the rule body is true. These bodies will typically be made up of multiple inputs, with the head composed of the name of the rule (such as “allow” or “deny”) and the value to assign (such as true/false, but could be any JSON value.

Another important concept in getting started with Rego is understanding how to define constants, as well as partial rules. Constants are the easy part of this equation, as a user needs only to omit the rule body. Once constants are defined, they can be queried like any other value you’ve defined in OPA. 

Partial rules are slightly more engaging to write, as they return to being if-then statements, with the exception that they generate a set of values and assign that set to a variable. Notice that where the first ruleset was true, this new ruleset inserts a variable in its place. This changes its function to confirming that net.id is in the public network, rather than confirming any_public_networks as true.

The above rule is the same one we saw earlier, which allows users to check public_network for specific id using syntax, and is able to do so through expression of the logical AND. In Rego, this takes the form of splitting expressions across lines. However, Rego also allows you to express a logical OR, by defining multiple rules with the same name. For example, a user could check if their servers are giving clients shell access by defining shell access with the logical OR.

Finally, we can pull everything we’ve learned together and write some code for ourselves. Let’s assume we have multiple servers running, and we need to check if they are in violation of certain conditions. We could write code like so to achieve that:

Now you know the basics of writing your first rules in Rego! From here, the sky’s the limit for you and your servers, as more integrations for OPA and Rego are found every day, and you could be the first to crack a new one!

If you’d like to learn to write Rego yourself, you can view a more hands-on tutorial on how to author OPA policy, as our very own Styra Academy has a course covering the topic. If you’re familiar with OPA already and want to flex your policy authoring muscle, try out your skills in the Rego Playground.

Cloud native
Authorization

Entitlement Explosion Repair

Join Styra and PACLabs on April 11 for a webinar exploring how organizations are using Policy as Code for smarter Access Control.

Speak with an Engineer

Request time with our team to talk about how you can modernize your access management.