OPA for All: Policy as Code in 10 Minutes
Open Policy Agent, or OPA, has emerged as an industry standard for cloud-native authorization and policy as code. From 2018 to now, it has grown from being a Cloud Native Computing Foundation (CNCF) sandbox project into a fully mature, graduated CNCF project, deployed by many of the largest organizations in the world. (For just the tip of the iceberg, here is a list of users who have made their adoption of OPA public).
OPA provides an intuitive rule language, Rego, to help policy authors clearly define the policies that make authorization decisions — whether a particular user can access a particular microservice, for instance. However, some new OPA users have found it a mental leap to get used to this way of thinking. So to help, I’m sharing the one mental model you need to make sense of everything related to OPA policy. Whether you’re a seasoned coder looking for the 5-minute OPA quick-start or just making your first foray into computer code, this post will help you gain a solid foundation in OPA policy in under 10 minutes. All you need to get started is a basic familiarity with spreadsheets!
OPA policy with spreadsheets
If you can understand spreadsheet formulas, you can understand OPA policy. Let’s start with an example spreadsheet that contains the formulas to determine, say, whether a customer is allowed to post a review online. In this example, the policy allows the customer to post a review if they have purchased the product in question and have a high enough reputation score.
Figure 1. The input values are to the left (colored yellow) and the computed values to the right (colored green).
Figure 2. The formula checks the purchase history cell to determine whether the customer has made a verified purchase. (The simplifying assumption that the purchase history refers to a single product will be relaxed later).
Figure 3. The formula determines the user’s reputation score (calculated as the number of upvotes minus the number of downvotes).
Figure 4. The formula, in the form of an IF construct, makes a final decision about whether to allow the review or not. If cell E2 is TRUE (verified purchase) and cell E3 (reputation score) is at least zero, then the final decision (cell E5) is set to TRUE (allow the review).
OPA is a spreadsheet!
You’re now 90% of the way to understanding how an OPA policy works! That’s because an OPA policy IS essentially just a spreadsheet with some fancy features. To complete the last 10%, let’s make a few syntax tweaks to turn this spreadsheet into an official OPA policy.
Step 1: Write down the three spreadsheet formulas:
Step 2: Then, we make some basic syntax tweaks:
- Use the OPA “==” operator instead of the Google Sheet “=” operator for the equality check.
- Use the OPA assignment operator := to indicate cell value assignment.
- Precede each input cell reference with “input.”
Step 3 (last step!): Rearrange the IF construct into OPA’s simpler form:
In OPA’s policy language, the IF-condition is given inside the {…}-block. Multiple conditions, usually written as one per line as shown here, are implicitly ANDed together. That is, the cell value assignment takes place if ALL the conditions inside the {…}-block succeed.
In step 3, we have officially arrived at an OPA policy defining the logic of the spreadsheet! If there is any doubt, you can evaluate the OPA policy by visiting the OPA Playground example and clicking the blue “Evaluate” button near the top-right corner. The following screenshot is what you will see.
Congratulations! You now have a foundational understanding of OPA policy! Everything else in OPA policy is mere bells and whistles added to this foundation. To show what I mean, let’s tweak this example just a little further to demonstrate two simple but powerful extensions beyond the basic spreadsheet.
Naming cells with OPA (we’ll call them variables)
As we create more complex real-world policies, we don’t want to be stuck with these meaningless cell references. Let’s use OPA’s flexibility to make the policy more readable by using meaningful names. To borrow familiar programming lingo, we call these “named cells” “variables” in OPA. Nevertheless, they are really more like spreadsheet cells in that once a value is computed in the course of an evaluation, that value does not change again until a new evaluation starts (as when a user modifies the value of an input cell in a spreadsheet).
Using structured data
So far, we have used a simplifying assumption that the purchase history is a single product. In reality, a user’s purchase history is likely to be more complex than a single value. This situation is a bit complicated to deal with in the traditional spreadsheet, but it is very simple in OPA — because OPA’s hierarchical data model allows for complex data structures within each “cell” or “variable.” For example, a user’s purchase history can be represented as a list of values, each representing one product the user has purchased. That way, we can write policies (“formulas”) that dig into the structure using OPA’s rich expressions. In this case, we use the “in” operator to check that the product being reviewed is somewhere in the list of products in the user’s purchase history.
See the updated OPA Playground example with the revised rules and inputs.
Next steps
OPA is packed with tons more features that help you create exactly the policy you want, anywhere across the cloud-native stack. Popular use cases include application authorization for API gateways, microservices and service meshes (Envoy, Istio, Kong, Kuma, Gloo and the like), Kubernetes admissions control, Terraform infrastructure-as-code validation and many more. This spreadsheet mental model will no doubt serve you well as you pick up all the OPA features you need for your next project!
As you continue your policy-as-code journey, take advantage of my and others’ courses on the free Styra Academy, including a complete course on OPA policy authoring, an intermediate course on OPA performance and application-focused courses on Terraform validation and microservices authorization using OPA with Styra technology. Happy learning!