CoursesPolicy-as-code at scaleGatekeeper ConstraintTemplates at scale

Gatekeeper ConstraintTemplates at scale

Templates, constraints, and syncing data.

In short. Gatekeeper wraps OPA for Kubernetes with ConstraintTemplates (Rego + schema) and Constraints (parameters + selectors).

Advanced30 min · lesson 6 of 13

Gatekeeper wraps OPA for Kubernetes with ConstraintTemplates (Rego + schema) and Constraints (parameters + selectors). At scale the template is the product: one well-tested template parameterized many ways beats twenty near-copies. Syncing cluster data into OPA (config.gatekeeper.sh) lets policies reason about existing Inventory — for example, denying Services that reference non-existent Secrets is a data problem, not just an input problem.

Start in dry-run (enforcementAction: dryrun), watch violations, then flip to deny by namespace wave. Treat template upgrades like schema migrations.

Template + constraint

ConstraintTemplate (sketch)
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[_]
satisfied := [r | r := input.parameters.repos[_]; startswith(container.image, r)]
not count(satisfied)
msg := sprintf("image %v not from allowed repos", [container.image])
}
terminal
kubectl apply -f template.yaml
kubectl apply -f constraint.yaml
kubectl get K8sAllowedRepos
kubectl get constraints -o wide 2>/dev/null | head
output
NAME ENFORCEMENT-ACTION
allowed-repos-prod dryrun
Gatekeeper decision path
1API request
AdmissionReview
2Gatekeeper
evaluate constraints
3OPA/Rego
violation set
4Allow/deny
per enforcementAction
Match constraints with namespace selectors so platform and product clusters can share templates with different parameters.
Rego in CRDs still needs tests
Keep the same Rego in a repo with opa test; do not let the cluster be your only compiler.

Going deeper

Match constraints with label selectors and namespace selectors to avoid boiling the ocean on day one. Platform namespaces often need different parameters than product namespaces. Multi-tenant clusters benefit from templates that take repos as parameters rather than hardcoding.

Watch Gatekeeper audit and webhook latency SLOs. Slow admission is an availability incident. Profile expensive Rego (unbounded comprehensions over large lists) before enforcing in prod.

Backup ConstraintTemplates in Git even if the live cluster is the apply target. Disaster recovery of policy is part of cluster DR — empty Gatekeeper after rebuild means open floodgates.

Use enforcementAction: dryrun and warn thoughtfully: warn can train teams to ignore. Publish a date when dry-run becomes deny, and meet it. Rolling forever in dry-run is how risk becomes culture.

Separate mutating admission from validating Gatekeeper policies operationally — ordering and failure modes differ. Document which webhook fails open vs closed in an outage.

Name constraints after the control (deny-privileged-prod), not after the requester. Inventory them in a catalog page so app teams can discover standards before they invent exceptions.

When upgrading Gatekeeper, read the release notes for Rego/API changes and re-run opa test plus a canary cluster. Policy engines are load-bearing infrastructure.

Keep a lab cluster on the next Gatekeeper version ahead of prod so template upgrades are rehearsed. Policy control planes deserve the same canary discipline as application runtimes.

Try this

Install Gatekeeper in a kind cluster (or use an existing lab), apply a dry-run allowed-repos constraint, and create a violating Pod to see the violation object.

terminal
kubectl get k8sallowedreposallowedrepos.constraints.gatekeeper.sh -o yaml | head -40
output
status:
totalViolations: 1
violations:
- …

Takeaway

Gatekeeper scales when templates are libraries, constraints are parameters, dry-run precedes deny, and Rego stays under unit test outside the cluster.

Next: Kyverno's mutate, generate, and verifyImages — policy that fixes and proves, not only rejects.

Quick check
01A ConstraintTemplate primarily defines…
Incorrect — No.
Correct —
Incorrect — Helm may deliver it; it is not the definition.
Incorrect — Wrong cloud.
02dryrun enforcement is useful to…
Incorrect — No.
Correct —
Incorrect — Opposite of intent.
Incorrect — Unrelated.

Related