← Back to DevBytes

Gatekeeper: Complete Configuration Guide

Introduction to Gatekeeper

Gatekeeper is a Kubernetes-native policy controller that integrates Open Policy Agent (OPA) with the Kubernetes API server. It allows platform teams to enforce custom policies across clusters by defining declarative constraints and auditing existing resources for compliance. Gatekeeper leverages Kubernetes Custom Resource Definitions (CRDs) to manage policies as code, making it an essential tool for governance, security, and compliance in cloud-native environments.

Why Gatekeeper Matters

🚀 Deploy your AI agent in 10 minutes

Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.

Try it free →

In Kubernetes, RBAC controls who can do what, but it doesn’t answer questions like “What labels must a namespace have?” or “Which image registries are allowed?”. Gatekeeper fills this gap by enforcing fine-grained policies that govern the properties of resources, not just access. It provides:

Core Concepts

Gatekeeper operates around three key object types:

A typical workflow: you create a Constraint Template that contains the Rego policy logic, then instantiate it with one or more Constraints that provide the specific configuration (e.g., allowed image prefixes). Gatekeeper evaluates incoming admission requests against the constraints and, if configured, denies non-compliant requests.

Installation and Setup

Gatekeeper can be installed via Helm or static manifests. The recommended approach is Helm, as it allows easier upgrades and configuration.

Using Helm

# Add the OPA Gatekeeper Helm repository
helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts
helm repo update

# Install Gatekeeper in the gatekeeper-system namespace
helm install gatekeeper gatekeeper/gatekeeper --namespace gatekeeper-system --create-namespace

After installation, verify the CRDs and controller pods are running:

kubectl get crd | grep gatekeeper
kubectl -n gatekeeper-system get pods

Key Configuration Flags

Common Helm values to customize:

Defining Constraint Templates

A Constraint Template defines the policy logic in Rego and the parameters users can supply. The template must include targets: admission.k8s.gatekeeper and a crd specification.

Example: a template that requires all namespaces to have a label owner.

apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
  name: k8srequiredlabels
  annotations:
    description: "Requires a label on all namespaces."
spec:
  crd:
    spec:
      names:
        kind: K8sRequiredLabels
      validation:
        openAPIV3Schema:
          type: object
          properties:
            labels:
              type: array
              items:
                type: string
  targets:
    - target: admission.k8s.gatekeeper
      rego: |
        package k8srequiredlabels

        get_message(parameters) = {
          "message": sprintf("Missing required labels: %v", [missing_labels])
        }

        violation[{"msg": msg}] {
          provided := {label | input.review.object.metadata.labels[label]}
          required := {label | parameters.labels[label]}
          missing := required - provided
          count(missing) > 0
          msg := get_message(parameters).message
        }

The crd section defines the schema for the constraint parameters. The rego block contains the policy logic. The violation rule produces a message when a required label is missing.

Creating Constraints

Once the template exists, you can create a Constraint that references it. The constraint specifies match criteria (which resources to evaluate) and the parameters.

Example: require namespaces with the label owner set to any value.

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
  name: ns-require-owner-label
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Namespace"]
    namespaces: [] # apply to all namespaces
  parameters:
    labels: ["owner"]

To target specific namespaces, use excludedNamespaces or namespaces lists in match.

Dry-Run Constraints

Gatekeeper supports an enforcementAction field (set via spec.enforcementAction). Valid values: deny (default), dryrun. A dryrun constraint logs violations but does not block admission. This is perfect for testing policies before full enforcement.

spec:
  enforcementAction: dryrun
  match: ...
  parameters: ...

Audit and Violations

Gatekeeper’s audit functionality periodically scans existing resources and records violations in the constraint’s status field. View violations with:

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

Or use the dedicated command (if gatekeeper CLI installed). The audit interval can be adjusted via Helm value auditInterval.

Best Practices

Conclusion

Gatekeeper transforms Kubernetes governance into a transparent, code-driven process. By defining Constraint Templates and Constraints, platform teams can enforce everything from labeling requirements to container security standards without handcrafting admission webhooks. The combination of admission-time enforcement and periodic auditing ensures both preventive and detective controls. Adopting best practices like dry-run testing, parameterization, and Git-based policy management will help you build a robust, scalable governance framework that evolves with your clusters. Start with simple label requirements, expand to image policies, and gradually secure your entire fleet with confidence.

🚀 Need a reliable AI agent for your project?

Deploy Hermes Agent in 10 minutes. Managed hosting, zero DevOps.

Get Started — $23.99/mo
← Back to all articles