Portal | Level: L2: Operations | Topics: Policy Engines, RBAC | Domain: Kubernetes
Policy Engines (OPA/Kyverno) - Primer¶
Why This Matters¶
RBAC controls who can do what. Policy engines control what can exist. They enforce organizational standards at the API level: no pods without resource limits, no images from untrusted registries, no privileged containers. Without policy enforcement, one misconfigured deployment can compromise your cluster.
The Problem¶
Kubernetes RBAC answers: "Can this user create a Deployment?" Policy engines answer: "Should this specific Deployment be allowed?"
RBAC: "Developer can create pods in namespace X" (identity-based)
Policy: "All pods must have resource limits" (content-based)
OPA Gatekeeper vs Kyverno¶
| Feature | OPA Gatekeeper | Kyverno |
|---|---|---|
| Policy language | Rego (custom DSL) | YAML (native K8s) |
| Learning curve | Steep (Rego is unique) | Low (just YAML) |
| Validation | Yes | Yes |
| Mutation | Limited | Yes (first-class) |
| Generation | No | Yes (auto-create resources) |
| Community | CNCF graduated (OPA) | CNCF incubating |
| Best for | Complex logic, multi-platform | K8s-native teams |
Kyverno¶
Installation¶
helm repo add kyverno https://kyverno.github.io/kyverno/
helm install kyverno kyverno/kyverno -n kyverno --create-namespace
Policy Types¶
| Type | What it does |
|---|---|
| Validate | Block or warn on non-compliant resources |
| Mutate | Automatically modify resources |
| Generate | Auto-create companion resources |
| VerifyImages | Check container image signatures |
Validate: Require Resource Limits¶
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-limits
spec:
validationFailureAction: Enforce # or Audit
rules:
- name: check-limits
match:
any:
- resources:
kinds:
- Pod
validate:
message: "CPU and memory limits are required"
pattern:
spec:
containers:
- resources:
limits:
memory: "?*"
cpu: "?*"
Validate: Restrict Image Registries¶
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-registries
spec:
validationFailureAction: Enforce
rules:
- name: validate-registries
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Images must come from ghcr.io or docker.io"
pattern:
spec:
containers:
- image: "ghcr.io/* | docker.io/*"
Validate: Disallow Privileged Containers¶
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-privileged
spec:
validationFailureAction: Enforce
rules:
- name: no-privileged
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Privileged containers are not allowed"
pattern:
spec:
containers:
- securityContext:
privileged: "!true"
Mutate: Add Default Labels¶
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: add-labels
spec:
rules:
- name: add-team-label
match:
any:
- resources:
kinds:
- Pod
mutate:
patchStrategicMerge:
metadata:
labels:
managed-by: kyverno
environment: "{{request.namespace}}"
Generate: Auto-Create NetworkPolicy¶
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: generate-netpol
spec:
rules:
- name: default-deny
match:
any:
- resources:
kinds:
- Namespace
generate:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
name: default-deny
namespace: "{{request.object.metadata.name}}"
data:
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
OPA Gatekeeper¶
Installation¶
helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts
helm install gatekeeper gatekeeper/gatekeeper -n gatekeeper-system --create-namespace
How It Works¶
- Define a ConstraintTemplate (the policy logic in Rego)
- Create a Constraint (apply the template with parameters)
ConstraintTemplate: Require Labels¶
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 required labels: %v", [missing])
}
Constraint: Apply the Template¶
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
name: require-team-label
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Namespace"]
parameters:
labels: ["team", "environment"]
Rego Basics¶
# Deny if container image uses 'latest' tag
package k8sdisallowlatest
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
endswith(container.image, ":latest")
msg := sprintf("Container %v uses :latest tag", [container.name])
}
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not contains(container.image, ":")
msg := sprintf("Container %v has no tag (defaults to :latest)", [container.name])
}
Audit Mode vs Enforce Mode¶
| Mode | Behavior |
|---|---|
| Enforce | Reject non-compliant resources at admission |
| Audit/Warn | Allow resources but log violations |
Rollout strategy:
1. Deploy policies in Audit mode
2. Review violations: kubectl get policyreport -A (Kyverno) or kubectl get constraint -o yaml
3. Fix existing violations
4. Switch to Enforce mode
Pod Security Standards¶
Kubernetes has built-in Pod Security Standards (replacing PodSecurityPolicies):
# Apply Pod Security Standards via namespace labels
kubectl label namespace grokdevops \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/warn=restricted \
pod-security.kubernetes.io/audit=restricted
| Level | What it allows |
|---|---|
| Privileged | Everything (no restrictions) |
| Baseline | Prevents known privilege escalations |
| Restricted | Strongly restricted (non-root, no caps, read-only root) |
Common Policies Every Cluster Should Have¶
- Require resource limits - Prevent noisy neighbors
- Disallow privileged containers - Security baseline
- Restrict image registries - Only trusted sources
- Require non-root user - Reduce attack surface
- Disallow latest tag - Ensure reproducibility
- Require labels - Cost allocation and ownership
- Default deny NetworkPolicy - Network segmentation
- Disallow hostPath volumes - Prevent host filesystem access
Common Pitfalls¶
- Enforcing too early — Start in Audit mode. Enforcing immediately breaks existing workloads.
- No exceptions — Some system pods need privileges. Use exclusions for kube-system.
- Policy conflicts — A mutating policy and validating policy can fight. Test together.
- Webhook failures — If Kyverno/Gatekeeper is down, the webhook blocks all resource creation. Set
failurePolicy: Ignorefor non-critical policies. - Performance — Complex Rego policies add latency to every API call. Keep policies simple.
Wiki Navigation¶
Prerequisites¶
- Kubernetes Ops (Production) (Topic Pack, L2)
Next Steps¶
- Policy Engine Drills (Drill, L2)
- Skillcheck: Policy Engines (Assessment, L2)
Related Content¶
- Multi-Tenancy Patterns (Topic Pack, L2) — RBAC, Policy Engines
- Interview: Kyverno Blocking Deploys (Scenario, L2) — Policy Engines
- Interview: RBAC Forbidden (Scenario, L2) — RBAC
- K8s RBAC (Topic Pack, L1) — RBAC
- Kubernetes Exercises (Quest Ladder) (CLI) (Exercise Set, L1) — RBAC
- Kubernetes RBAC Flashcards (CLI) (flashcard_deck, L1) — RBAC
- Kubernetes Security Flashcards (CLI) (flashcard_deck, L1) — RBAC
- Policy Engine Drills (Drill, L2) — Policy Engines
- Policy Engines Flashcards (CLI) (flashcard_deck, L1) — Policy Engines
- Runbook: Kyverno Blocking Workloads (Runbook, L2) — Policy Engines
Pages that link here¶
- Anti-Primer: Policy Engines
- Certification Prep: CKA — Certified Kubernetes Administrator
- Certification Prep: CKAD — Certified Kubernetes Application Developer
- Certification Prep: CKS — Certified Kubernetes Security Specialist
- Comparison: Policy Engines
- K8S Rbac
- Kubernetes Ecosystem - Primer
- Level 6: Advanced Platform Engineering
- Master Curriculum: 40 Weeks
- Multi-Tenancy Patterns
- Policy Engine Drills
- Policy Engines (OPA / Kyverno)
- Policy Engines - Skill Check
- Production Readiness Review: Answer Key
- Production Readiness Review: Study Plans