OPA Rego: Policy Language for Cloud-Native Systems

Rego is the declarative policy language used by Open Policy Agent (OPA). It is designed to express policies over complex hierarchical data structures, enabling fine-grained policy enforcement across cloud-native systems including Kubernetes, APIs, Terraform, and microservices.

OPA Rego: Policy Language for Cloud-Native Systems

Rego is the declarative policy language used by Open Policy Agent (OPA), a Cloud Native Computing Foundation project. Rego is designed specifically for expressing policies over complex, hierarchical data structures common in cloud-native environments. It enables fine-grained, context-aware policy enforcement across systems including Kubernetes admission control, API gateways, Terraform infrastructure as code, microservices authorization, and CI/CD pipelines.

To understand OPA Rego properly, it helps to be familiar with policy as code concepts, JSON data structures, and Kubernetes security.

OPA Rego architecture:
┌─────────────────────────────────────────────────────────────────────────┐
│                           OPA Rego Architecture                          │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  ┌─────────────────────────────────────────────────────────────────────┐│
│  │                         Policy Definition                            ││
│  │  ┌─────────────────────────────────────────────────────────────┐    ││
│  │  │  package policy.kubernetes                                   │    ││
│  │  │                                                              │    ││
│  │  │  default allow = false                                       │    ││
│  │  │                                                              │    ││
│  │  │  allow {                                                     │    ││
│  │  │      input.request.user == "admin"                           │    ││
│  │  │  }                                                           │    ││
│  │  │                                                              │    ││
│  │  │  deny[msg] {                                                 │    ││
│  │  │      not allow                                               │    ││
│  │  │      msg = "Access denied"                                   │    ││
│  │  │  }                                                           │    ││
│  │  └─────────────────────────────────────────────────────────────┘    ││
│  └─────────────────────────────────────────────────────────────────────┘│
│                                    │                                     │
│                                    ▼                                     │
│  ┌─────────────────────────────────────────────────────────────────────┐│
│  │                         OPA Evaluation Engine                        ││
│  │                                                                      ││
│  │   Data Documents ──┐                                                ││
│  │   (JSON/YAML)      │                                                ││
│  │                    ├──→ Evaluation ──→ Decision (allow/deny)       ││
│  │   Input (Request) ─┘                                                ││
│  │                                                                      ││
│  └─────────────────────────────────────────────────────────────────────┘│
│                                    │                                     │
│                                    ▼                                     │
│  ┌─────────────────────────────────────────────────────────────────────┐│
│  │                         Integration Points                           ││
│  │                                                                      ││
│  │  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐            ││
│  │  │Kubernetes│  │ Terraform│  │   APIs   │  │   Envoy  │            ││
│  │  │Gatekeeper│  │ Conftest │  │  (AuthZ) │  │  (mTLS)  │            ││
│  │  └──────────┘  └──────────┘  └──────────┘  └──────────┘            ││
│  └─────────────────────────────────────────────────────────────────────┘│
│                                                                          │
│  Key Characteristics: Declarative, Hierarchical data support,           │
│                      Partial evaluation, Built-in functions            │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

What Is OPA Rego?

Rego is a declarative query language designed for policy as code. Unlike general-purpose programming languages, Rego is optimized for evaluating hierarchical data and making policy decisions based on rules. Rego policies are evaluated by OPA, which takes policy code and input data to produce allow or deny decisions.

  • Declarative Logic: Policies express what is allowed or forbidden, not how to enforce it. You state desired conditions, and OPA figures out evaluation.
  • Hierarchical Data Support: Rego navigates JSON, YAML, and other nested data structures with dot notation and comprehensions.
  • Rule-Based Evaluation: Policies consist of rules that produce true or false values. Rules can reference each other and combine logically.
  • Partial Evaluation: OPA can evaluate policies partially, returning queries that can be pushed to databases or other systems for optimization.
  • Built-in Functions: Rego includes functions for string manipulation, regular expressions, cryptography, sets, and JSON operations.

Why OPA Rego Matters

As systems grow in complexity, traditional policy enforcement mechanisms like hardcoded conditions or external decision services become inadequate. Rego provides a unified, declarative approach to policy across diverse systems.

  • Unified Policy Language: Same Rego syntax works for Kubernetes, Terraform, APIs, and microservices.
  • Decoupled Policy from Code: Policies written in Rego separate from application code allow policy changes without redeployment.
  • Fine-Grained Control: Express complex policies like role-based access, time-based restrictions, or resource labeling requirements.
  • Performance Optimization: Partial evaluation and indexing make policy evaluation efficient even with large inputs.
  • Rich Ecosystem: Integrates with Kubernetes (Gatekeeper), Terraform (Conftest), Envoy, and custom systems via SDKs.
  • Auditability: Rego policies are human-readable, version controllable, and decisions can be logged and explained.

Core Rego Concepts

Rego evaluation model:
Evaluation Flow:

Data Documents ──┐
(JSON/YAML)      │
                 ├──→ OPA Evaluation Engine ──→ Decision
Input (Request) ─┘    (Rule Evaluation)        (allow/deny)

Policy Evaluation Steps:
1. Load policy modules (Rego files)
2. Load data documents (JSON)
3. Receive input request
4. Evaluate query against rules
5. Return decision output

Key Concepts:
• Rules – Conditional logic producing a value
• Data – External data (user roles, config)
• Input – The request being evaluated
• Default – Fallback value when no rule matches
• Comprehensions – Generate collections from data

Built-in Functions Categories

  • String Functions: contains, startswith, endswith, lower, upper, substring, split, replace, sprintf.
  • Regular Expressions: regex.match, regex.find_all_string_submatch, regex.globs_match.
  • Aggregation: count, sum, max, min, sort, any, all.
  • Set Operations: union, intersect, difference, and as a subset of b.
  • Object Operations: object.get, object.union, object.remove, object.filter.
  • JSON and Encoding: json.marshal, json.unmarshal, base64.encode, base64.decode.
  • Time Functions: time.now_ns, time.parse_rfc3339_ns, time.add_date, time.diff.

Keywords Summary

Keyword Purpose
package Declare policy module namespace
import Load external data or functions
default Default rule value when no match
else Alternative rule when previous fails
with Override data or input for evaluation
not Negate condition
Common Rego policy structure:
Policy Structure Pattern:

package policy

default request_allowed = false

deny[message] {
    some violation condition
    message = sprintf("Violation: %v", [reason])
}

allow {
    not deny[_]
    request_allowed = true
}

request_allowed = true {
    allow rule conditions
}

Test Structure:
• Positive test – Should pass when conditions met
• Negative test – Should fail when conditions not met
• Edge cases – Empty input, missing fields, boundaries

Rego for Kubernetes (Gatekeeper)

Gatekeeper integrates OPA as Kubernetes admission controller. Policies are written as Constraint Templates defining Rego logic and Constraints configuring template parameters.

Common Kubernetes Policies in Rego

  • Image Registry Restrictions: Require images from approved registries, deny from untrusted sources.
  • Required Labels: Enforce labels like owner, environment, cost-center on all resources.
  • Container Security: Require runAsNonRoot, disallow privileged containers, require read-only root filesystem.
  • Resource Limits: Enforce CPU and memory limits on containers.
  • Namespace Isolation: Restrict resource creation in specific namespaces.
  • Ingress Security: Require TLS for ingress resources.

Rego for Terraform (Conftest)

Conftest uses Rego to test structured configuration files including Terraform, Kubernetes manifests, Dockerfiles, and CloudFormation.

Common IaC Policies in Rego

  • Security Group Rules: Deny overly permissive rules (0.0.0.0/0 on SSH/RDP).
  • Resource Tagging: Enforce required tags like environment, owner, cost-center.
  • Instance Types: Restrict which EC2 instance types can be used.
  • Storage Encryption: Require encryption for S3 buckets, RDS, EBS volumes.
  • Public Accessibility: Prevent S3 buckets or databases from being publicly accessible.
  • Naming Conventions: Enforce naming patterns matching organizational standards.

Rego for API Authorization

OPA can serve as external authorization service for APIs and microservices.

Common API Policies in Rego

  • Role-Based Access Control: Grant access based on user roles.
  • Attribute-Based Access Control: Decisions based on user, resource, and environment attributes.
  • Time-Based Restrictions: Allow access only during business hours.
  • Resource Ownership: Only allow users to access resources they own.
  • Contextual Rules: Deny access from untrusted IP ranges.

Rego Anti-Patterns

  • Procedural Thinking: Writing Rego like imperative code with loops and mutable state. Rego is declarative.
  • Inefficient Comprehensions: Nested comprehensions over large data sets cause performance issues.
  • Rule Duplication: Copying rules instead of using rule references and abstraction.
  • Ignoring Default Rules: Not providing default rule values causes undefined decisions.
  • Deep Nesting: Deeply nested rule bodies are hard to read and debug.
  • Large Rules: Single massive rule with many conditions is unmaintainable.
  • No Testing: Policies untested and prone to logic errors.
Rego policy quality checklist:
Policy Quality Indicators:

□ Clear package name (policy.domain.area)
□ Default rules defined
□ Small, focused rules
□ Meaningful variable names
□ Comments explaining policy purpose
□ Comprehensive test coverage
□ Input validation present
□ No unnecessary nesting
□ Efficient comprehensions
□ Documentation for exceptions

Best Practices:
• Use clear package names (hierarchical by domain)
• Write declaratively (what, not how)
• Leverage rule references (compose, don't duplicate)
• Provide default values (closed-world assumption)
• Test thoroughly (positive, negative, edge cases)
• Version control all policies (code review, audit)

Rego Best Practices

  • Use Clear Package Names: Organize policies hierarchically like policy.kubernetes.network or policy.terraform.aws.
  • Write Declaratively: Express what you want, not how to compute it. Let Rego handle execution.
  • Use Small, Focused Rules: Each rule checks one specific condition for easier understanding and testing.
  • Leverage Rule References: Compose policies by referencing other rules instead of duplicating conditions.
  • Provide Default Values: Always include default rule for closed-world assumption.
  • Test Thoroughly: Write comprehensive policy tests covering positive, negative, and edge cases.
  • Use Meaningful Variable Names: Descriptive names like container, image_name, or violation indicate purpose.
  • Document Policy Purpose: Comment why rule exists, what it enforces, and any exceptions.
  • Version Control Policies: Store Rego files in version control with code review and audit history.
  • Use Built-in Functions: Prefer built-in functions over custom implementations.

Learning Rego Resources

  • OPA Playground: Browser-based environment to experiment with Rego policies.
  • Rego Cheatsheet: One-page reference of syntax, built-in functions, and patterns.
  • Policy Library: Community-maintained collection of example policies.
  • Interactive Tutorials: Official OPA tutorials teach Rego through hands-on exercises.

Frequently Asked Questions

  1. What is the difference between OPA and Rego?
    OPA is the Open Policy Agent engine that evaluates policies. Rego is the language used to write those policies. You write policies in Rego, OPA executes them.
  2. Is Rego similar to JSONPath or XPath?
    Rego is more powerful. While JSONPath and XPath extract data, Rego evaluates logical rules with conditions, cross-references, and custom logic.
  3. Do I need to learn Rego separately from Kubernetes?
    Yes, if you use Gatekeeper or other OPA integrations. Custom policies require understanding Rego, though pre-built templates exist.
  4. How does Rego compare to regular expression or SQL?
    Rego is different. Regular expressions match string patterns. SQL queries relational databases. Rego evaluates logical rules over hierarchical data, combining aspects of JavaScript navigation, Prolog-style logic, and functional comprehensions.
  5. Is Rego difficult to learn?
    Rego has a learning curve, especially for imperative programmers. The declarative, unification-based approach is different. Most engineers become productive with basic Rego within days.
  6. What should I learn next after OPA Rego?
    After mastering Rego, explore policy as code patterns, Gatekeeper for Kubernetes, Conftest for Terraform, advanced Rego techniques, and policy testing strategies.