Policy Engines Cheat Sheet¶
Remember: Kyverno vs OPA Gatekeeper decision shortcut: if your team already knows Rego, use Gatekeeper. If not, use Kyverno — its YAML-native policies have a much lower learning curve. Kyverno also does mutation and generation (auto-create resources), which Gatekeeper does not support natively. Both work as Kubernetes admission webhooks that intercept API requests before they are persisted.
Kyverno vs OPA Gatekeeper¶
| Feature | Kyverno | OPA Gatekeeper |
|---|---|---|
| Language | YAML (native K8s) | Rego (custom DSL) |
| Learning curve | Low | High |
| Policy types | Validate, Mutate, Generate, VerifyImages | Validate only (+ mutation in beta) |
| Policy format | ClusterPolicy CRD | ConstraintTemplate + Constraint |
| Audit mode | validationFailureAction: Audit |
enforcementAction: dryrun |
Kyverno¶
Validate — Block Non-Compliant Resources¶
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-labels
spec:
validationFailureAction: Enforce # Enforce | Audit
rules:
- name: check-team-label
match:
any:
- resources:
kinds: ["Deployment", "StatefulSet"]
validate:
message: "Label 'team' is required."
pattern:
metadata:
labels:
team: "?*"
Mutate — Auto-Fix Resources¶
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: add-default-requests
spec:
rules:
- name: add-cpu-memory-requests
match:
any:
- resources:
kinds: ["Pod"]
mutate:
patchStrategicMerge:
spec:
containers:
- (name): "*"
resources:
requests:
cpu: "100m"
memory: "128Mi"
Generate — Auto-Create Resources¶
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: generate-networkpolicy
spec:
rules:
- name: default-deny
match:
any:
- resources:
kinds: ["Namespace"]
generate:
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
name: default-deny
namespace: "{{request.object.metadata.name}}"
data:
spec:
podSelector: {}
policyTypes: ["Ingress", "Egress"]
Image Verification¶
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: verify-images
spec:
rules:
- name: verify-cosign
match:
any:
- resources:
kinds: ["Pod"]
verifyImages:
- imageReferences: ["registry.example.com/*"]
attestors:
- entries:
- keys:
publicKeys: |-
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
OPA Gatekeeper¶
ConstraintTemplate (Define the Rule)¶
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8srequiredlabels
spec:
crd:
spec:
names:
kind: K8sRequiredLabels
validation:
openAPIV3Schema:
type: object
properties:
labels:
type: array
items: { type: string }
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredlabels
violation[{"msg": msg}] {
provided := {label | input.review.object.metadata.labels[label]}
required := {label | label := input.parameters.labels[_]}
missing := required - provided
count(missing) > 0
msg := sprintf("Missing labels: %v", [missing])
}
Constraint (Apply the Rule)¶
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
name: require-team-label
spec:
enforcementAction: deny # deny | dryrun | warn
match:
kinds:
- apiGroups: ["apps"]
kinds: ["Deployment"]
parameters:
labels: ["team", "env"]
Pod Security Standards (Built-in)¶
# Label-based enforcement (no extra tools needed)
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
Levels: privileged → baseline → restricted
Useful Commands¶
# Kyverno
kubectl get clusterpolicy
kubectl get policyreport -A # Audit results
kubectl get clusterpolicyreport # Cluster-scoped results
# Gatekeeper
kubectl get constrainttemplates
kubectl get constraints # All constraint types
kubectl get k8srequiredlabels -o yaml # Specific constraint + violations
# Test a resource against policies (Kyverno CLI)
kyverno apply policy.yaml --resource resource.yaml
Gotcha: Policy engine webhooks are a single point of failure for the entire cluster. If the webhook pod is down and
failurePolicy: Fail(the secure default), no resources can be created in the cluster — including the webhook pod itself (deadlock). Always run policy engine pods with high priority, anti-affinity across nodes, and considerfailurePolicy: Ignorefor non-critical policies in non-production clusters.
Rollout Strategy¶
1. Deploy policies in Audit mode
2. Review violations in policy reports
3. Fix existing violations
4. Switch to Enforce mode
5. Monitor for new violations