Open Policy Agent (OPA) is a general-purpose, CNCF-graduated policy engine that decouples policy decision-making from application and infrastructure code, using its declarative language Rego to evaluate structured data such as API requests, Kubernetes manifests, and IaC configurations. Gatekeeper extends OPA into a Kubernetes-native admission controller, providing CRD-based policy management via ConstraintTemplates and Constraints. The core mental model to internalize is that OPA never enforces by itself β it only decides; enforcement always lives in the caller (webhook, sidecar, CI step) that acts on OPA's response.
What This Cheat Sheet Covers
This topic spans 23 focused tables and 216 indexed concepts. Below is a complete table-by-table outline of this topic, spanning foundational concepts through advanced details.
Table 1: Rego Language Fundamentals
Rego is a declarative, Datalog-inspired query language purpose-built for policy evaluation over JSON/YAML documents. Understanding how Rego evaluates rules β as logical assertions rather than imperative instructions β is the foundation for writing correct policies across all OPA use cases.
| Concept | Example | Description |
|---|---|---|
package authz | β’ Namespaces rules β’ the package path determines the OPA data document path (e.g., data.authz). | |
allow if { input.method == "GET"} | β’ Complete rule with a single value β’ in Rego v1 (OPA 1.0+) the if keyword is mandatory before the rule body | |
default allow := false | β’ Provides a fallback value when no other rule matches β’ prevents undefined decisions, which differ from false. | |
input.user.role == "admin" | β’ The JSON object passed to OPA at query time β’ represents the request, event, or resource being evaluated | |
data.roles["admin"] | OPA's in-memory store for base documents (static JSON/YAML loaded via API, bundles, or Gatekeeper sync). | |
x := 42 | β’ Unification with explicit assignment β’ preferred over bare = for readability in Rego v1. | |
input.count == 5 | β’ Strict equality check β’ unlike :=, does not bind variables | |
x = 42 | β’ Simultaneously binds and tests β’ evaluates to undefined if unification fails, which can be a gotcha. | |
not input.privileged | β’ Negation-as-failure: true when the expression under not is undefined or falseβ’ cannot bind new variables | |
some i; input.users[i].role == "admin" | β’ Declares a local variable for iteration β’ makes the variable's scope explicit and prevents shadowing | |
every user in input.users { user.active == true} | β’ Universally quantifies over a collection β’ rule body must be true for every element or the expression fails | |
"admin" in input.roles | β’ Membership test β’ also used with some for explicit iteration over collections |