What Is OPA Gatekeeper in Kubernetes?

advanced|securitydevopssreplatform engineerCKA
TL;DR

OPA Gatekeeper is a Kubernetes-native policy engine that uses a validating admission webhook to enforce custom policies written in Rego. It provides constraint templates for reusable policy definitions and constraints for applying them to specific resources.

Detailed Answer

OPA Gatekeeper brings the Open Policy Agent (OPA) to Kubernetes as a native admission controller. It intercepts API requests and evaluates them against policies you define, blocking requests that violate your rules.

Architecture

kubectl apply → API Server → Gatekeeper Webhook → Policy Decision
                                    ↓
                              ConstraintTemplates (Rego logic)
                              Constraints (parameters + targets)
                                    ↓
                              Allow / Deny + Reason

Installation

kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/deploy/gatekeeper.yaml

# Verify installation
kubectl get pods -n gatekeeper-system
kubectl get crd | grep gatekeeper

ConstraintTemplate: Define the Policy

A ConstraintTemplate defines reusable policy logic in 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, "details": {"missing_labels": missing}}] {
          provided := {label | input.review.object.metadata.labels[label]}
          required := {label | label := input.parameters.labels[_]}
          missing := required - provided
          count(missing) > 0
          msg := sprintf("Missing required labels: %v", [missing])
        }

Constraint: Apply the Policy

A Constraint instantiates a template with specific parameters:

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
  name: require-team-label
spec:
  enforcementAction: deny
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Namespace"]
      - apiGroups: ["apps"]
        kinds: ["Deployment"]
    excludedNamespaces:
      - kube-system
      - gatekeeper-system
  parameters:
    labels:
      - "team"
      - "environment"

Now any Deployment or Namespace without team and environment labels is rejected:

kubectl create deployment nginx --image=nginx
# Error: admission webhook denied the request:
# Missing required labels: {"environment", "team"}

Common Policy Examples

Deny Privileged Containers

apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
  name: k8sdenyprivileged
spec:
  crd:
    spec:
      names:
        kind: K8sDenyPrivileged
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8sdenyprivileged

        violation[{"msg": msg}] {
          container := input.review.object.spec.containers[_]
          container.securityContext.privileged == true
          msg := sprintf("Privileged container not allowed: %v", [container.name])
        }

        violation[{"msg": msg}] {
          container := input.review.object.spec.initContainers[_]
          container.securityContext.privileged == true
          msg := sprintf("Privileged init container not allowed: %v", [container.name])
        }

Enforce Resource Limits

apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
  name: k8srequireresourcelimits
spec:
  crd:
    spec:
      names:
        kind: K8sRequireResourceLimits
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8srequireresourcelimits

        violation[{"msg": msg}] {
          container := input.review.object.spec.containers[_]
          not container.resources.limits.cpu
          msg := sprintf("Container %v must have CPU limits", [container.name])
        }

        violation[{"msg": msg}] {
          container := input.review.object.spec.containers[_]
          not container.resources.limits.memory
          msg := sprintf("Container %v must have memory limits", [container.name])
        }

Restrict Image Registries

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

        violation[{"msg": msg}] {
          container := input.review.object.spec.containers[_]
          not startswith(container.image, input.parameters.repos[_])
          msg := sprintf("Container %v uses image %v which is not from an allowed registry", [container.name, container.image])
        }

Enforcement Actions

| Action | Behavior | |--------|----------| | deny | Reject the request | | dryrun | Allow the request but log the violation | | warn | Allow but return a warning to the user |

Start with dryrun to understand impact before switching to deny:

spec:
  enforcementAction: dryrun

Audit Mode

Gatekeeper periodically audits existing resources against all constraints:

# View audit violations
kubectl get k8srequiredlabels require-team-label -o yaml
# status.violations lists all existing resources that violate the policy

kubectl get constraint -o json | jq '.items[].status.violations'

Gatekeeper vs. Kyverno

| Feature | Gatekeeper | Kyverno | |---------|-----------|---------| | Policy language | Rego | YAML | | Learning curve | Steep | Low | | Mutation support | Limited (alpha) | Full | | Generation (create resources) | No | Yes | | Audit existing resources | Yes | Yes | | CNCF status | Graduated (OPA) | Graduated |

Best Practices

  1. Start with dryrun — deploy all constraints in dryrun mode first to assess impact
  2. Exclude system namespaces — always exclude kube-system and gatekeeper-system
  3. Use the Gatekeeper library — the gatekeeper-library repo contains pre-built ConstraintTemplates
  4. Monitor webhook latency — Gatekeeper adds latency to API requests
  5. Set failurePolicy carefullyFail blocks all requests if Gatekeeper is down, Ignore bypasses policy

Why Interviewers Ask This

Policy enforcement is critical for multi-tenant clusters and compliance. This question tests your ability to implement guardrails that prevent misconfigurations before they reach production.

Common Follow-Up Questions

What is the difference between a ConstraintTemplate and a Constraint?
A ConstraintTemplate defines the policy logic in Rego (like a class). A Constraint instantiates that template with specific parameters and target resources (like an object).
How does Gatekeeper differ from Kyverno?
Gatekeeper uses Rego for policies (powerful but complex). Kyverno uses YAML-based policies (simpler, Kubernetes-native). Kyverno also supports mutation, while Gatekeeper focuses on validation.
Can Gatekeeper audit existing resources?
Yes — Gatekeeper's audit controller periodically scans existing resources against constraints and reports violations, even for objects created before the policy was applied.

Key Takeaways

  • Gatekeeper enforces policies as a validating admission webhook — violations are blocked before reaching etcd.
  • ConstraintTemplates define reusable policy logic; Constraints apply them to specific resources.
  • The audit feature detects policy violations in existing resources, not just new requests.

Related Questions

You Might Also Like