OPA Gatekeeper on Kubernetes

πŸ“– Introduction

Setting up a raw OPA admission webhook in Kubernetes by hand is instructive once β€” you learn exactly what's happening under the hood. But Gatekeeper is the practical path. It wraps OPA with a Kubernetes-native API: ConstraintTemplates define policy schemas, Constraints instantiate them, and the framework handles webhook registration, status reporting, and audit mode automatically.

This article walks through installing Gatekeeper on a local cluster and understanding its architecture before we write actual policies in Article 05.


πŸ—οΈ Gatekeeper Architecture

Gatekeeper extends Kubernetes with two custom resource types:

  • ConstraintTemplate β€” defines a new constraint kind and the Rego policy logic behind it

  • Constraint β€” an instance of a ConstraintTemplate with specific parameters applied to specific resources

spinner

The separation of template and instance is powerful:

  • One template (e.g., RequiredLabels) defines the policy logic once

  • Multiple constraints can instantiate it with different parameters for different namespaces or resource types


πŸ”„ How the Admission Flow Works

spinner

Gatekeeper also runs in audit mode β€” it periodically re-checks all existing resources against all active constraints and reports violations in the constraint's status. This catches resources that predate a policy or were created while Gatekeeper was down.


πŸ“¦ Installing Gatekeeper

Prerequisites

Install via Manifest (Alternative)

Verify Installation

Three components:

  • controller-manager β€” handles admission webhook requests (2 replicas for HA)

  • audit β€” periodically re-evaluates existing resources

Check the validating webhook was registered:


🧩 ConstraintTemplate Structure

A ConstraintTemplate has two parts:

  1. CRD schema β€” defines the custom resource (the Constraint kind) and any parameters it accepts

  2. Rego targets β€” the actual policy logic

Key things to notice:

  • The Rego package name matches the template name by convention

  • input.review.object is the Kubernetes resource being evaluated

  • input.parameters contains the values from the Constraint instance

  • Violations are expressed as a set β€” each element must have a msg field


πŸŽ›οΈ Constraint Structure

Once a ConstraintTemplate is installed (and its CRD is created), you instantiate it with a Constraint:

This constraint:

  • Uses the K8sRequiredLabels template

  • Matches all Namespace resources

  • Requires the labels team and environment

Apply both:

Test it:


πŸ” Scoping Constraints

The match field controls what a constraint applies to:

This granularity lets you roll out policies incrementally β€” start with one namespace or resource type, expand as you gain confidence.


πŸ“‹ Checking Constraint Status

After applying a constraint, check its status for audit results:

Look for the status.violations field β€” it lists all currently violating resources:

This is audit mode in action β€” existing resources that violate the policy are reported without blocking them (unless enforcementAction: deny is set).


⚠️ Enforcement Actions

Gatekeeper supports three enforcement actions:

Action
Behavior

deny

Block the admission request

warn

Allow but return a warning message

dryrun

Allow; only report violations in status

Set it in the Constraint:

dryrun is invaluable when rolling out a new policy: you can see what would be blocked before actually blocking anything.


πŸ›‘οΈ Exempting Namespaces

Gatekeeper itself (and Kubernetes system namespaces) should be exempt from most policies. Configure exemptions at the Gatekeeper level:

Or per-constraint via excludedNamespaces in the match spec.


🧭 What's Next

You now have Gatekeeper running and understand how templates and constraints work together. The next article focuses on writing real, practical Kubernetes policies β€” pod security, image registries, resource limits, and more.

Next: Article 05 β€” Writing Kubernetes Admission Policies


πŸ“Ž References

Last updated