KCSA — Pod Security Admission (PSA)
What Is Pod Security Admission?
Pod Security Admission (PSA) is the built-in Kubernetes admission controller that enforces Pod Security Standards (PSS). While PSS defines the security levels (Privileged, Baseline, Restricted), PSA is the mechanism that actually validates pods against those levels.
Key Point: PSS = the policy definition. PSA = the enforcement engine.
PSA operates at the namespace level — you apply PSA configuration to namespaces using labels, and all pods created in that namespace are evaluated against the configured PSS level.
The Three PSA Modes
PSA supports three modes that determine what happens when a pod violates the configured PSS level:
| Mode | Behavior | Pod Created? | Use Case |
|---|---|---|---|
| enforce | Rejects non-compliant pods | ❌ No | Production enforcement |
| audit | Logs violations to the audit log, allows pods | ✅ Yes | Monitoring compliance |
| warn | Sends a warning to the user, allows pods | ✅ Yes | Migration and transition |
Mode Details
-
enforce — The strictest mode. Non-compliant pods are rejected and will not be created. The user sees an error message explaining why.
-
audit — Violations are recorded in the Kubernetes audit log but the pod is allowed to run. This is useful for tracking how many workloads would break under a given PSS level without actually blocking them.
-
warn — The API server sends a warning header in the response. The user sees a warning message (e.g., in
kubectloutput) but the pod is allowed to run. This is ideal for educating developers about compliance issues.
Exam Tip: Only enforce mode actually prevents pods from being created. Both audit and warn allow the pod to run.
Namespace Labels for PSA
PSA is configured entirely through namespace labels. No CRDs, no webhook configurations — just labels.
Label Format
pod-security.kubernetes.io/<MODE>: <LEVEL>
pod-security.kubernetes.io/<MODE>-version: <VERSION>
Where:
<MODE>isenforce,audit, orwarn<LEVEL>isprivileged,baseline, orrestricted<VERSION>is a Kubernetes minor version (e.g.,v1.28) orlatest
Full Label Reference
| Label | Purpose |
|---|---|
pod-security.kubernetes.io/enforce |
PSS level to enforce (reject violations) |
pod-security.kubernetes.io/enforce-version |
Kubernetes version for enforce policy |
pod-security.kubernetes.io/audit |
PSS level to audit (log violations) |
pod-security.kubernetes.io/audit-version |
Kubernetes version for audit policy |
pod-security.kubernetes.io/warn |
PSS level to warn (show warnings) |
pod-security.kubernetes.io/warn-version |
Kubernetes version for warn policy |
YAML Examples
Namespace with Restricted Enforcement
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: latest
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/audit-version: latest
pod-security.kubernetes.io/warn: restricted
pod-security.kubernetes.io/warn-version: latest
This namespace will:
- Reject any pod that does not meet the Restricted level
- Log all violations to the audit log
- Warn users about violations in
kubectloutput
Namespace with Baseline Enforcement
apiVersion: v1
kind: Namespace
metadata:
name: development
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/enforce-version: latest
pod-security.kubernetes.io/warn: restricted
pod-security.kubernetes.io/warn-version: latest
This namespace will:
- Reject pods that violate the Baseline level
- Warn users if their pods don’t meet the Restricted level (but still allow them)
This is a common pattern for gradually moving toward Restricted compliance.
Combining Modes — The Migration Strategy
One of the most powerful features of PSA is the ability to combine modes at different levels. This is the recommended approach for migrating to stricter security:
Recommended Combination
| Mode | Level | Purpose |
|---|---|---|
| enforce | baseline | Block the most dangerous pods now |
| audit | restricted | Track what would break under Restricted |
| warn | restricted | Show developers what needs to change |
apiVersion: v1
kind: Namespace
metadata:
name: staging
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
Why this works:
- Dangerous pods (privileged, hostNetwork) are immediately blocked (enforce: baseline)
- The audit log captures every pod that wouldn’t pass Restricted (audit: restricted)
- Developers see warnings telling them exactly what to fix (warn: restricted)
- Once all warnings are resolved, you can upgrade enforce to restricted
Migration from PSP to PSA
If you’re migrating from PodSecurityPolicy to PSA, follow this 3-step process:
Step 1: Assess Current State
- Identify all namespaces and their current PSP bindings
- Determine which PSS level matches each namespace’s current PSP
- Use
auditandwarnmodes to test without breaking anything
# Add labels to test without enforcement
labels:
pod-security.kubernetes.io/audit: baseline
pod-security.kubernetes.io/warn: baseline
Step 2: Enable Enforcement Gradually
- Start with
enforce: baselineon non-critical namespaces - Monitor audit logs for violations
- Fix workloads that fail Baseline compliance
- Move to production namespaces
# Enable enforcement after testing
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/warn: restricted
Step 3: Tighten to Restricted
- Once all Baseline violations are resolved, upgrade
- Use
warn: restrictedfirst to identify remaining issues - Switch
enforcetorestrictedwhen ready
# Final state for production
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
Exempt Namespaces
Some namespaces need to run privileged workloads and should be exempted from PSA enforcement.
Common Exemptions
| Namespace | Why It’s Exempted |
|---|---|
kube-system |
Control plane components need host access |
kube-node-lease |
Node heartbeat pods |
kube-public |
Public cluster information |
Configuring Exemptions
PSA exemptions are configured in the admission controller configuration file (typically /etc/kubernetes/psa/config.yaml on the API server):
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: PodSecurity
configuration:
apiVersion: pod-security.admission.config.k8s.io/v1
kind: PodSecurityConfiguration
defaults:
enforce: "baseline"
enforce-version: "latest"
audit: "restricted"
audit-version: "latest"
warn: "restricted"
warn-version: "latest"
exemptions:
usernames: []
runtimeClasses: []
namespaces:
- kube-system
- kube-node-lease
- kube-public
Note: Exemptions can be based on usernames, runtimeClasses, or namespaces. For the KCSA exam, focus on namespace-level exemptions.
PSA Behavior with Workload Controllers
An important nuance: PSA evaluates the pod template inside workload controllers (Deployments, DaemonSets, StatefulSets, etc.), not just standalone pods.
| Action | enforce Mode | audit/warn Modes |
|---|---|---|
| Create a non-compliant Pod directly | ❌ Rejected | ✅ Allowed (with audit/warn) |
| Create a Deployment with non-compliant pod template | ✅ Deployment created | ✅ Allowed (with audit/warn) |
| Deployment tries to create a non-compliant Pod | ❌ Pod rejected | ✅ Allowed (with audit/warn) |
Important: In enforce mode, a non-compliant Deployment is not rejected, but the pods it tries to create are. This means the Deployment will exist but have zero available replicas. The audit and warn modes catch this at Deployment creation time.
Verifying PSA Configuration
To check which PSA labels are set on a namespace:
kubectl get namespace production --show-labels
To see PSA warnings when creating a pod:
kubectl --dry-run=server -n production apply -f pod.yaml
The --dry-run=server flag sends the request to the API server for validation without actually creating the resource. You’ll see any PSA warnings in the output.
Common Misconceptions
| Misconception | Reality |
|---|---|
| “PSA requires installing a webhook” | No — PSA is a built-in admission controller |
| “PSA is configured with CRDs” | No — PSA uses namespace labels |
| “enforce mode blocks Deployments” | No — it blocks the pods the Deployment tries to create |
| “You can only use one mode per namespace” | No — you can combine all three modes at different levels |
| “PSA replaces OPA/Gatekeeper” | Not necessarily — PSA handles standard policies; OPA handles custom policies |
Key Takeaways for the Exam
-
PSA is the enforcement mechanism for Pod Security Standards. It’s a built-in admission controller.
-
Three modes:
enforce(reject),audit(log),warn(warn). Onlyenforceblocks pods. -
PSA is configured through namespace labels — no CRDs or webhooks needed.
-
Combine modes for gradual migration: enforce=baseline + warn=restricted is a common pattern.
-
Exempt namespaces like
kube-systemthat need privileged access. -
PSA evaluates pod templates in workload controllers during
auditandwarn, but only blocks actual pods inenforcemode. -
The version label (
enforce-version: latest) controls which Kubernetes version’s PSS definition is used for evaluation.
Next: Security Contexts — the pod and container-level fields that implement security controls.