Free — no signup required

The Language: Rego

2 min read

Declarative Policy, Not Imperative Code

Rego (pronounced "ray-go") is OPA's purpose-built query language. It is fundamentally different from languages like Python or Go. You don't write step-by-step instructions ("first do this, then check that, then return this"). Instead, you write declarations about what a violation looks like. The OPA engine figures out how to evaluate them.

The mental model: instead of writing "IF label is missing THEN deny", you write "A violation EXISTS WHEN a label is missing." The engine evaluates whether that condition is true for the given input.

The Input Object

When Gatekeeper calls your Rego, it provides a structured JSON object called input. The most important fields are:

  • input.review.object — the full Kubernetes resource being created/updated (the YAML you applied, as JSON).
  • input.parameters — the values from the parameters field of the matching Constraint.

A Complete Rego Example: Required Labels

package k8srequiredlabels

# The 'violation' rule is special — Gatekeeper looks for this rule.
# If it produces any results, the request is denied.
violation[{"msg": msg}] {

  # Step 1: Extract the set of labels actually present on the resource.
  # The '|' syntax is a set comprehension — like a set() in Python.
  provided := {label | input.review.object.metadata.labels[label]}

  # Step 2: Extract the set of required labels from the Constraint's parameters.
  # input.parameters.labels is an array; '_' iterates over it.
  required := {label | label := input.parameters.labels[_]}

  # Step 3: Set subtraction — find labels that are required but not provided.
  missing := required - provided

  # Step 4: If 'missing' is non-empty, this block evaluates to true,
  # and the violation is triggered with a formatted message.
  count(missing) > 0
  msg := sprintf("Resource is missing required labels: %v", [missing])
}

Key insight: Every statement inside the violation block is an implicit AND. All conditions must be true for the violation to fire. If any single condition is false (e.g., count(missing) > 0 is false because no labels are missing), the entire block short-circuits and no violation is produced.

The ConstraintTemplate YAML That Wraps This Rego

apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
  name: k8srequiredlabels
spec:
  crd:
    spec:
      names:
        kind: K8sRequiredLabels
      validation:
        openAPIV3Schema:
          type: object
          properties:
            labels:
              type: array
              items:
                type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8srequiredlabels

        violation[{"msg": msg}] {
          provided := {label | input.review.object.metadata.labels[label]}
          required := {label | label := input.parameters.labels[_]}
          missing := required - provided
          count(missing) > 0
          msg := sprintf("Resource is missing required labels: %v", [missing])
        }

This is one of 18 chapters

Every chapter is free — Kubernetes, Terraform, SRE, distributed systems, and more — with fast daily review built in.

Sign up free