> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# OPA Gatekeeper Constraint Based Policy Enforcement

> Describes OPA Gatekeeper's two resource model for enforcing Kubernetes admission policies with reusable Rego templates, constraint parameters, rollout strategies, and debugging guidance.

Gatekeeper is a Kubernetes policy engine built on top of Open Policy Agent (OPA). It uses a two-resource model to separate reusable policy logic from the per-use configuration that applies that logic across the cluster. After reading this guide you'll understand how ConstraintTemplates and Constraints work together, be able to author an exam-level Rego policy for admission control, and roll out policies safely with a predictable debug workflow.

Why this matters: consider a healthcare environment that must enforce HIPAA-safe configurations across multiple namespaces. CI/CD checks are helpful but can be bypassed by direct `kubectl apply`. Gatekeeper enforces policies at the API server level, preventing misconfigurations regardless of how a resource is created.

![An infographic showing a healthcare/hospital scene with two people talking to a clinician, a HIPAA symbol and the text "12 Namespaces." To the left are security warnings and red X icons listing container/Kubernetes issues like "a pod without encryption labels," "a container running as root," and "an image from Docker Hub."](https://mintcdn.com/kodekloud-c4ac6d9a/jFwNGqGMK4QeJs-g/images/Prep-Course-Certified-Cloud-Native-Platform-Engineering-CNPE/Security-and-Policy-Enforcement/OPA-Gatekeeper-Constraint-Based-Policy-Enforcement/healthcare-hipaa-12-namespaces-kubernetes-warnings.jpg?fit=max\&auto=format\&n=jFwNGqGMK4QeJs-g\&q=85\&s=40111e088ab235845b3aa96a5fcc2860)

## Gatekeeper two-resource model

Gatekeeper policies are composed from two distinct Kubernetes resources:

* ConstraintTemplate — authored by platform/security teams. Contains Rego logic and defines a new CustomResourceDefinition (CRD).
* Constraint — an instance of the CRD created by the template. Provides match criteria, parameter values, and enforcement behavior.

The separation allows you to write policy logic once and reuse it with different parameters and match rules.

![An infographic comparing "ConstraintTemplate" (left) and "Constraint" (right) for webhooks. The left explains that a ConstraintTemplate defines a CRD and contains Rego logic and reusable parameters, while the right shows a Constraint is an instance that specifies match criteria, provides parameter values, and controls enforcement.](https://mintcdn.com/kodekloud-c4ac6d9a/jFwNGqGMK4QeJs-g/images/Prep-Course-Certified-Cloud-Native-Platform-Engineering-CNPE/Security-and-Policy-Enforcement/OPA-Gatekeeper-Constraint-Based-Policy-Enforcement/constrainttemplate-vs-constraint-webhook-infographic.jpg?fit=max\&auto=format\&n=jFwNGqGMK4QeJs-g\&q=85\&s=1c89fb6ef5bc6c9a75024db8dc858454)

## Example: Enforce required labels

Below is a concrete, commonly used example: require specific labels on objects. The ConstraintTemplate defines a kind named `K8sRequiredLabels` and exposes a `labels` parameter (array of strings). The Rego policy inspects the admission review object (`input.review.object`) and the parameters passed from a Constraint (`input.parameters.labels`). If a required label is missing, the policy emits a violation.

```yaml theme={null}
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
  name: k8srequiredlabels

spec:
  crd:
    spec:
      names:
        kind: K8sRequiredLabels
      validation:
        openAPIV3Schema:
          properties:
            labels:
              type: array
              items:
                type: string

  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8srequiredlabels

        violation[{"msg": msg}] {
          provided := input.review.object
          required := input.parameters.labels
          label := required[_]
          not provided.metadata.labels[label]
          msg := sprintf("missing: %v", [label])
        }
```

Important notes:

* The template creates a CRD with kind `K8sRequiredLabels`. Constraints must use that kind.
* Use `input.review.object` to reference the resource being admitted.
* Constraint parameters are available as `input.parameters`.

Now create a Constraint that uses the template. The `spec.enforcementAction` controls behavior: `deny` blocks requests, `dryrun` records violations without blocking, and `warn` allows the request but surfaces warnings. The `spec.match` field determines which resources are evaluated.

```yaml theme={null}
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
  name: require-team-label

spec:
  enforcementAction: deny

  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Namespace"]

  parameters:
    labels: ["team"]
```

If a developer attempts to create a namespace without the `team` label, Gatekeeper rejects the request with a clear message:

```bash theme={null}
$ kubectl create ns test-ns
Error from server: admission webhook "validation.gatekeeper.sh" denied the request: missing: "team"
```

Constraint parameters map directly into Rego as `input.parameters`, so the template contains the reusable logic while the constraint supplies the context and values.

Rollout strategy: start with `dryrun` to collect violations without blocking resources, then move to `warn` to surface non-blocking warnings, and finally switch to `deny` for strict enforcement once teams have remediated issues.

## Enforcement actions quick reference

| Action | Behavior | Use case |
| - | - | - |
| `dryrun` | Records violations in status but does not block requests | Initial rollout and discovery of violations |
| `warn` | Allows request but surfaces warnings to users | Alerting teams while still allowing progress |
| `deny` | Blocks requests that violate policy | Final enforcement after remediation |

## Debugging Gatekeeper and checking status

Common tasks for debugging Gatekeeper and verifying policy behavior:

* Check ConstraintTemplates and their readiness:
  * `kubectl get constrainttemplates` shows templates and their status; a non-ready template often indicates Rego syntax or schema errors.
* List constraints of a particular kind:
  * `kubectl get k8srequiredlabels` shows instances and their enforcement actions and violation counts.
* View violation messages for a specific constraint:
  * `kubectl get k8srequiredlabels require-team-label -o jsonpath='{.status.violations[*].message}'`
* Inspect Gatekeeper controller logs for errors:
  * `kubectl logs -n gatekeeper-system deployment/gatekeeper-controller-manager`

Commands and expected outputs:

| Command | Purpose | Example output |
| - | - | - |
| `kubectl get constrainttemplates` | List templates and readiness | NAME: `k8srequiredlabels` — STATUS: `True` |
| `kubectl get k8srequiredlabels` | List Constraint instances | NAME: `require-team-label` — ENFORCEMENT: `deny` — TOTAL-VIOLATIONS: `12` |
| `kubectl get k8srequiredlabels require-team-label -o jsonpath='{.status.violations[*].message}'` | Show violation messages | `missing: "team"` (one or many messages) |
| `kubectl logs -n gatekeeper-system deployment/gatekeeper-controller-manager` | Inspect controller errors | Controller logs with Rego compile or webhook errors |

Common checks when a policy isn't working:

* Rego or schema errors in the ConstraintTemplate (inspect `kubectl describe constrainttemplate <name>` and template status).
* Webhook configuration issues (validating webhook not reachable or misconfigured).
* Gatekeeper controller pod not running or repeatedly crashing (check controller deployment and logs).
* Match expressions do not cover the intended resources (verify `spec.match` in Constraint).

## Common pitfalls and tips

* Always validate Rego locally or in a CI step before applying ConstraintTemplates.
* Use small, focused templates to make debugging easier.
* Prefer parameterizing logic (via `input.parameters`) rather than hardcoding resource names or labels.
* When onboarding teams, start with `dryrun` to avoid accidental outages and to build trust.

## Wrapping up

Gatekeeper’s two-resource model gives platform teams a reliable way to enforce cluster-wide policies with reusable Rego logic and flexible parameterization. Remember:

* Write the Rego logic in a ConstraintTemplate and expose only the parameters you need.
* Use Constraints to scope where the policy applies and to safely roll out enforcement via `dryrun` → `warn` → `deny`.
* Use Kubernetes primitives and Gatekeeper status fields to debug and iterate quickly.

## Links and references

* Gatekeeper project: [https://github.com/open-policy-agent/gatekeeper](https://github.com/open-policy-agent/gatekeeper)
* Open Policy Agent (OPA): [https://www.openpolicyagent.org/](https://www.openpolicyagent.org/)
* Rego language: [https://www.openpolicyagent.org/docs/latest/policy-language/](https://www.openpolicyagent.org/docs/latest/policy-language/)
* Kubernetes admission webhooks: [https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/)

> **[Watch Video](https://learn.kodekloud.com/user/courses/prep-course-certified-cloud-native-platform-engineer-cnpe/module/35a7fadb-02d8-4557-a819-2e4dcfa970cc/lesson/f677c67f-5636-431f-9ce8-edca2d1c5c9d)**


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.