BlogKubernetes

OPA Gatekeeper: writing constraint templates from scratch

Enforce org-wide Kubernetes policy with Rego — required labels, blocked images, and audit of existing violations.

Dec 3, 2025·12 min readAdvanced

OPA Gatekeeper is an admission controller that enforces policy written in Rego. You define a reusable ConstraintTemplate (the logic) once, then stamp out Constraints (the parameters) for each rule. Together they reject non-compliant objects at the API server — and audit the ones already in the cluster.

How a rule is enforced
1
ConstraintTemplate
Rego logic
2
Constraint
params + scope
3
Admission
reject on create
4
Audit
flag existing

The template: require a label

template.yaml
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}] {
required := input.parameters.labels[_]
not input.review.object.metadata.labels[required]
msg := sprintf("missing required label: %v", [required])
}

The constraint: apply it

constraint.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata: { name: must-have-owner }
spec:
match:
kinds: [{ apiGroups: ["apps"], kinds: ["Deployment"] }]
parameters:
labels: ["owner"]
bash — it rejects on createlive
kubectl apply -f deploy-no-owner.yaml
admission webhook denied the request:
missing required label: owner
Roll out in dryrun first
Set spec.enforcementAction: dryrun, watch the audit results for a week, fix the violators, then flip to deny. Same audit-first discipline as Pod Security.
Go deeper in a courseOPA & RegoPolicy-as-code with OPA — Rego, Conftest, and Gatekeeper.View course

Related posts