title: "Monitoring OPA Gatekeeper: Policy Enforcement Observability in Kubernetes" description: "How to monitor OPA Gatekeeper constraint violations, audit results, webhook latency, and integrate policy enforcement observability with Vigilmon for Kubernetes platform teams." date: 2026-07-01 tags: [kubernetes, opa, gatekeeper, policy, monitoring, vigilmon]
OPA Gatekeeper enforces custom policies on Kubernetes resources via admission webhooks. When Gatekeeper is working correctly, policy violations are blocked at admission time and surfaced via audit. When it is not — webhook timeouts, crashing controller pods, misconfigured constraints — your cluster either enforces policy incorrectly or blocks legitimate workloads entirely. This guide covers how to observe Gatekeeper's behavior in production.
Gatekeeper Architecture
Gatekeeper has three main components:
- Admission webhook — validates resource creates/updates against active
Constraintobjects;failurePolicy: IgnoreorFaildetermines what happens when the webhook is down - Audit controller — periodically scans existing resources against constraints and writes violations to
Constraintstatus - Gatekeeper controller manager — reconciles
ConstraintTemplateandConstraintobjects, compiles Rego policies
Failure modes:
- Webhook latency exceeding the Kubernetes API server timeout (default 10s) triggers
failurePolicy - Controller manager OOM kills stall constraint compilation
- Audit controller falling behind means violations go undetected on existing resources
- Constraint compilation errors leave policies silently unenforced
Prometheus Metrics
Gatekeeper exposes metrics at :8888/metrics on the controller manager pod.
Scrape Configuration
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: gatekeeper-controller-manager
namespace: gatekeeper-system
spec:
selector:
matchLabels:
control-plane: controller-manager
gatekeeper.sh/system: "yes"
endpoints:
- port: metrics
path: /metrics
Admission Webhook Metrics
# Total admission requests handled
rate(gatekeeper_validations_total[5m])
# Admission denials by constraint
rate(gatekeeper_validations_total{admission_status="deny"}[5m]) by (constraint)
# Webhook request latency (p99)
histogram_quantile(0.99,
rate(gatekeeper_webhook_request_duration_seconds_bucket[5m])
)
High p99 webhook latency is the leading indicator of timeout-induced admission failures. Alert on it before the Kubernetes API server starts timing out requests.
Constraint Violation Metrics
# Total violations detected by audit
gatekeeper_violations{enforcement_action="deny"}
# Violations per constraint across all namespaces
gatekeeper_violations by (constraint, enforcement_action)
# Audit duration (long audits mean stale violation data)
gatekeeper_audit_duration_seconds
Constraint Compilation
# Constraints that failed to compile (active policy gap)
gatekeeper_constraint_template_ingestion_count{status="error"}
# Time to compile a constraint template
histogram_quantile(0.95,
rate(gatekeeper_constraint_template_ingestion_duration_seconds_bucket[5m])
)
A constraint_template_ingestion_count with status="error" means a Rego policy failed to compile — that constraint is silently not enforced.
Alerting Rules
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: gatekeeper-alerts
namespace: gatekeeper-system
spec:
groups:
- name: gatekeeper
rules:
- alert: GatekeeperWebhookHighLatency
expr: |
histogram_quantile(0.99,
rate(gatekeeper_webhook_request_duration_seconds_bucket[5m])
) > 5
for: 5m
labels:
severity: warning
annotations:
summary: "Gatekeeper webhook p99 latency {{ $value }}s — risk of API server timeouts"
- alert: GatekeeperConstraintCompileError
expr: gatekeeper_constraint_template_ingestion_count{status="error"} > 0
for: 1m
labels:
severity: critical
annotations:
summary: "Gatekeeper constraint template failed to compile — policy not enforced"
- alert: GatekeeperHighViolationCount
expr: sum(gatekeeper_violations{enforcement_action="deny"}) > 100
for: 10m
labels:
severity: warning
annotations:
summary: "{{ $value }} Gatekeeper violations detected — audit results need review"
- alert: GatekeeperControllerDown
expr: up{job="gatekeeper-controller-manager"} == 0
for: 2m
labels:
severity: critical
annotations:
summary: "Gatekeeper controller manager is down — policies may not be enforced"
- alert: GatekeeperAuditStale
expr: time() - gatekeeper_audit_last_run_time > 3600
for: 5m
labels:
severity: warning
annotations:
summary: "Gatekeeper audit has not run in >1 hour — violations may be undetected"
Inspecting Violations with kubectl
# List all constraints and their violation counts
kubectl get constraints -A
# Detailed violations for a specific constraint
kubectl describe constraint require-resource-limits
# All violations across all constraint types
kubectl get constraints -A -o json | \
python3 -c "
import json, sys
data = json.load(sys.stdin)
for item in data['items']:
violations = item.get('status', {}).get('violations', [])
if violations:
print(f\"\n=== {item['kind']}/{item['metadata']['name']} ===\")
for v in violations[:5]:
print(f\" {v.get('namespace','cluster')}/{v.get('name')}: {v.get('message')}\")
"
# Check constraint template compilation status
kubectl get constrainttemplate -o wide
# Gatekeeper controller logs
kubectl logs -n gatekeeper-system -l control-plane=controller-manager --tail=100
# Webhook configuration
kubectl get validatingwebhookconfigurations gatekeeper-validating-webhook-configuration -o yaml | \
grep -E "failurePolicy|timeoutSeconds"
The failurePolicy field is critical: Ignore means Gatekeeper downtime lets unenforced resources through; Fail means Gatekeeper downtime blocks all resource creation. Know which mode you are in and alert accordingly.
Audit Controller Observability
Audit runs on a configurable interval (default: 60 seconds) and writes violation counts to each Constraint's .status.violations field. Check audit health:
# Last audit timestamp on a constraint
kubectl get constraint require-labels -o jsonpath='{.status.auditTimestamp}'
# Total violations found in last audit
kubectl get constraint require-labels -o jsonpath='{.status.totalViolations}'
# Audit log from controller
kubectl logs -n gatekeeper-system deploy/gatekeeper-audit --tail=100 | grep -E "audit|violation"
Testing Policy Enforcement
After deploying a new constraint, verify it enforces correctly before trusting it in production:
# Attempt to create a resource that should be denied
kubectl run test-pod --image=nginx --namespace=production --dry-run=server
# If the constraint is working, you get:
# Error from server ([constraint-name] denied the request: ...)
# If it passes silently, check constraint compilation status:
kubectl describe constrainttemplate <template-name>
Vigilmon Integration
Monitor Webhook Availability
The most critical Gatekeeper component is the admission webhook. Add a Vigilmon TCP monitor:
- Go to Monitors → Add Monitor → TCP/Port
- Set host to the
gatekeeper-webhook-serviceClusterIP (or use a LoadBalancer with external access) - Set port to
8443 - Set check interval to 30 seconds
If the webhook pod crashes, this monitor fires within 30 seconds — before Kubernetes starts timing out admission requests.
Heartbeat for Audit Pipeline
If you run a custom audit export job (e.g., shipping violations to a SIEM or ticketing system), register a Vigilmon heartbeat:
#!/bin/bash
# audit-export.sh — runs every 5 minutes via CronJob
# Export Gatekeeper violations to SIEM
kubectl get constraints -A -o json | ./ship-violations-to-siem.py
# Signal health
curl -fsS "https://vigilmon.online/heartbeat/YOUR-HEARTBEAT-ID"
Configure the heartbeat period to 10 minutes — if the export job stops running, violations are no longer being tracked and compliance reporting silently goes dark.
Policy Compliance Status Page
Create a Vigilmon status page with a component per enforcement tier:
- Admission Enforcement — green when webhook is reachable and latency is normal
- Audit Coverage — green when heartbeat received from audit export within period
- Policy Compilation — green when no
ConstraintTemplateerrors detected
This gives your security and platform teams a shared view of policy enforcement health without requiring direct cluster access.
HTTPS Monitor for Policy Documentation
If you publish a human-readable policy catalog (e.g., a docs site or Confluence page describing what each constraint enforces), add a Vigilmon HTTPS monitor for that endpoint — broken documentation pages are a frequent operational gap during incident response.
Summary
| Signal | Metric / Resource | Alert Threshold |
|---|---|---|
| Webhook latency | gatekeeper_webhook_request_duration_seconds | p99 > 5s |
| Constraint compile failures | gatekeeper_constraint_template_ingestion_count{status="error"} | > 0 immediately |
| Violation count | gatekeeper_violations | Business-defined threshold |
| Audit freshness | gatekeeper_audit_last_run_time | > 1 hour since last run |
| Controller availability | up{job="gatekeeper-controller-manager"} | == 0 for 2m |
The highest-severity gap is a Fail mode webhook with the controller down — it blocks your entire cluster. Pair the GatekeeperControllerDown alert with a Vigilmon TCP probe on the webhook port for independent, out-of-band detection that does not depend on the same Prometheus stack running inside the cluster.