OPA Gatekeeper: about 50 policies, from audit to enforcement
Policy-as-code on three clusters, rolled out per environment, observable, with documented exceptions and gaps.
Context
Good practices in a wiki do not stop a risky deployment. The goals were explicit: block bad practices, standardise deployments and reduce the attack surface, on three clusters (production, pre-production, internal tools).
How it is built
- A custom chart carrying about 50 ConstraintTemplates from the official Gatekeeper library: container security (root, privilege escalation, read-only filesystem, capabilities, seccomp), trusted registries and no
:latest, resources, labels and probes, host isolation, exposed services. - Deployed by an ArgoCD ApplicationSet (clusters × per-cluster values), templates before constraints in sync waves. The CRD bootstrap gotcha on a fresh cluster is documented.
- Per-environment enforcement:
warnon pre-production,denyon production for the critical policies, one policy at a time.
The audit paid for itself
On pre-production, audit mode surfaced about 2,700 violations. Reading them revealed two misconfigurations that would have blocked the whole cluster in deny mode: an allowed-storage-class list that was empty because Gatekeeper was not syncing that resource, and an allowed-images list left empty. Both were fixed before enforcement.
Exceptions and gaps, written down
- Exemptions are per namespace and justified inline (runtime security, node exporter, secrets CSI driver, VPN client). No annotation bypass, on purpose: no untraceable escape hatch.
- Known gaps are documented rather than hidden: Traefik
IngressRouteCRDs are not covered by the native ingress templates, and secret values in environment variables are out of Gatekeeper’s reach. That risk is handled by Vault and secret scanning in CI.
Observable
Metrics and five Prometheus alert rules (violations, denies, stale audit, webhook errors, webhook latency) routed to Slack, plus a read-only policy UI with SSO on all three clusters.
Outcome
The platform moved from “recommended” to “enforced” without surprise outages. Next: checks in CI before merge (shift-left) and a policy requiring a NetworkPolicy in every namespace.