feat(kyverno): add policy engine with security baseline

- Kyverno 3.3.4 via Helm (HA config: 3 admission, 2 background replicas)
- Validation policies:
  - disallow-privileged-containers (Enforce)
  - require-resource-limits (Enforce)
  - require-labels (Audit - standard k8s labels)
  - require-run-as-non-root (Audit)
  - disallow-latest-tag (Enforce - GitOps reproducibility)
- Mutating policy:
  - add-default-securitycontext (seccomp, drop caps, read-only fs)
- System namespaces excluded (kube-system, kyverno, istio-system)
- Auto-discovered by ArgoCD ApplicationSet

Reference: CIS Kubernetes Benchmark, Pod Security Standards
This commit is contained in:
Greg Hendrickson
2026-02-09 18:02:21 +00:00
parent 124a29a0a9
commit 3752fd0386
10 changed files with 445 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
# infrastructure/kyverno/policies/require-labels.yaml
# Enforces standard labeling for all workloads
# Enables proper resource organization and cost tracking
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-labels
annotations:
policies.kyverno.io/title: Require Labels
policies.kyverno.io/category: Best Practices
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod, Deployment, StatefulSet, DaemonSet
policies.kyverno.io/description: >-
Labels are essential for organizing, filtering, and managing
Kubernetes resources. This policy requires standard labels on
all workloads.
spec:
validationFailureAction: Audit # Start in audit mode
background: true
rules:
- name: check-deployment-labels
match:
any:
- resources:
kinds:
- Deployment
- StatefulSet
- DaemonSet
exclude:
any:
- resources:
namespaces:
- kube-system
- kyverno
validate:
message: "Workloads must have 'app.kubernetes.io/name' and 'app.kubernetes.io/part-of' labels."
pattern:
metadata:
labels:
app.kubernetes.io/name: "?*"
app.kubernetes.io/part-of: "?*"
- name: check-pod-labels
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
- kyverno
# Exclude pods created by controllers (they inherit parent labels)
selector:
matchLabels:
app.kubernetes.io/managed-by: "*"
preconditions:
all:
# Only check standalone pods (not owned by ReplicaSet, etc.)
- key: "{{ request.object.metadata.ownerReferences[] || `[]` | length(@) }}"
operator: Equals
value: 0
validate:
message: "Pods must have 'app.kubernetes.io/name' label."
pattern:
metadata:
labels:
app.kubernetes.io/name: "?*"