Your pod creation is rejected with a security policy violation. Kubernetes enforces security policies that restrict pod capabilities, and violations can prevent pods from being created. Whether using legacy PodSecurityPolicy (deprecated) or Pod Security Standards (PSS), understanding security constraints is essential for deploying compliant pods.
Understanding Pod Security in Kubernetes
PodSecurityPolicy (PSP) was deprecated in Kubernetes 1.21 and removed in 1.25. Newer Kubernetes versions use Pod Security Standards (PSS) enforced through Pod Security Admission (PSA) or alternative admission controllers like OPA/Gatekeeper or Kyverno.
PSS defines three levels: - Privileged: Unrestricted (for system components) - Baseline: Minimal restrictions (prevents known escalations) - Restricted: Heavily restricted (for most workloads)
Diagnosis Commands
Check Pod Security Admission configuration:
```bash # Check namespace labels for PSA enforcement kubectl get namespace namespace-name --show-labels | grep pod-security
# Common PSA labels: # pod-security.kubernetes.io/enforce: restricted # pod-security.kubernetes.io/enforce-version: latest # pod-security.kubernetes.io/audit: restricted # pod-security.kubernetes.io/warn: restricted ```
Check pod rejection:
```bash # Check pod creation failure kubectl describe pod pod-name -n namespace | grep -A 10 "Error|Forbidden|denied"
# Check events for policy violations kubectl get events -n namespace | grep -i "policy|security|denied"
# Try dry-run to see warnings kubectl apply -f pod.yaml --dry-run=client -n namespace ```
Check PSP (legacy, Kubernetes < 1.25):
```bash # List PSPs kubectl get psp
# Describe PSP kubectl describe psp psp-name
# Check RBAC for PSP access kubectl get rolebindings -n namespace kubectl describe rolebinding binding-name -n namespace ```
Common Solutions
Solution 1: Fix PSS Level Violations
Pod violates the enforced PSS level:
# Check enforced level
kubectl get namespace namespace-name -o jsonpath='{.metadata.labels.pod-security\.kubernetes\.io/enforce}'Common violations and fixes:
Restricted Level Violations
Restricted level requires:
```yaml # Pod must meet restricted requirements: # 1. No privileged containers # 2. No hostPath volumes # 3. Containers must drop ALL capabilities # 4. Containers must run as non-root # 5. Seccomp profile must be RuntimeDefault or Localhost # 6. Read-only root filesystem (optional but recommended)
apiVersion: v1 kind: Pod metadata: name: compliant-pod spec: securityContext: runAsNonRoot: true runAsUser: 1000 seccompProfile: type: RuntimeDefault containers: - name: app image: myimage securityContext: allowPrivilegeEscalation: false capabilities: drop: - ALL runAsNonRoot: true readOnlyRootFilesystem: true ```
Fix non-compliant pod:
```yaml # Non-compliant pod containers: - name: app image: myimage # Missing security context - will violate restricted
# Fixed pod containers: - name: app image: myimage securityContext: allowPrivilegeEscalation: false capabilities: drop: - ALL runAsNonRoot: true # Pod-level seccompProfile # Or container-level seccompProfile ```
Solution 2: Change Namespace PSS Level
Relax namespace security level if pods need more capabilities:
```bash # Change to baseline level kubectl label namespace namespace-name pod-security.kubernetes.io/enforce=baseline
# Or privileged for system components kubectl label namespace namespace-name pod-security.kubernetes.io/enforce=privileged
# Remove enforcement label kubectl label namespace namespace-name pod-security.kubernetes.io/enforce- ```
Set different levels for audit and warn:
# Enforce baseline, audit restricted
kubectl label namespace namespace-name \
pod-security.kubernetes.io/enforce=baseline \
pod-security.kubernetes.io/audit=restricted \
pod-security.kubernetes.io/warn=restrictedSolution 3: Fix HostPath Volume Violation
PSS baseline and restricted block hostPath:
```yaml # Violating pod volumes: - name: host-volume hostPath: path: /data
# Fix: Use PVC instead volumes: - name: data-volume persistentVolumeClaim: claimName: my-pvc
# Or move to privileged namespace if hostPath needed kubectl label namespace namespace-name pod-security.kubernetes.io/enforce=privileged ```
Solution 4: Fix Privileged Container Violation
Privileged containers violate baseline and restricted:
```yaml # Violating pod containers: - name: app image: myimage securityContext: privileged: true # Violation
# Fix: Remove privileged flag containers: - name: app image: myimage securityContext: privileged: false # Or remove entirely
# If privileged needed, use privileged namespace kubectl label namespace namespace-name pod-security.kubernetes.io/enforce=privileged ```
Solution 5: Fix RunAsRoot Violation
Restricted level requires non-root:
```yaml # Violating pod containers: - name: app image: myimage # Runs as root by default - violation
# Fix: Set non-root user containers: - name: app image: myimage securityContext: runAsNonRoot: true runAsUser: 1000
# Or at pod level spec: securityContext: runAsNonRoot: true runAsUser: 1000 ```
Solution 6: Fix Capabilities Violation
Restricted requires dropping ALL capabilities:
```yaml # Violating pod containers: - name: app image: myimage securityContext: capabilities: add: - NET_ADMIN # Adding capabilities - violation
# Fix: Drop all capabilities containers: - name: app image: myimage securityContext: capabilities: drop: - ALL
# Or for baseline, specific restricted capabilities containers: - name: app image: myimage securityContext: capabilities: drop: - ALL # No adding capabilities allowed in restricted ```
Solution 7: Fix Seccomp Profile Violation
Restricted requires seccomp profile:
```yaml # Violating pod containers: - name: app image: myimage # No seccomp profile - violation
# Fix: Add seccomp profile spec: securityContext: seccompProfile: type: RuntimeDefault # Or Localhost with path
# Or container-specific containers: - name: app image: myimage securityContext: seccompProfile: type: RuntimeDefault ```
Solution 8: Use Pod Security Admission Warn Mode
Check what's wrong before enforcing:
```bash # Apply pod to see warnings kubectl apply -f pod.yaml -n namespace-name --dry-run=client
# View warnings in detail kubectl apply -f pod.yaml -n namespace-name
# Example warnings: # Warning: would violate PodSecurity "restricted:latest" # allowPrivilegeEscalation != false # runAsNonRoot != true ```
Solution 9: Handle Legacy PSP (Kubernetes < 1.25)
For older Kubernetes with PSP:
```bash # Check which PSP allows your pod kubectl auth can-i use psp/psp-name --as=system:serviceaccount:namespace:sa-name
# Check RBAC for PSP kubectl get clusterrolebindings | grep psp kubectl describe clusterrolebinding psp-binding ```
Grant PSP access:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: psp-binding
namespace: namespace
subjects:
- kind: ServiceAccount
name: default
namespace: namespace
roleRef:
kind: ClusterRole
name: psp:restricted
apiGroup: rbac.authorization.k8s.ioSolution 10: Use Alternative Admission Controllers
For advanced security policies, use OPA/Gatekeeper or Kyverno:
```bash # Check if Gatekeeper is installed kubectl get constrainttemplates
# Check Kyverno policies kubectl get policies -n namespace ```
Example Gatekeeper constraint:
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sContainerLimits
metadata:
name: container-must-have-limits
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
parameters:
cpu: "500m"
memory: "512Mi"Verification
After fixing security policy issues:
```bash # Check pod created successfully kubectl get pods -n namespace
# Verify pod security context kubectl get pod pod-name -n namespace -o yaml | grep -A 20 securityContext
# Check no warnings kubectl apply -f pod.yaml -n namespace --dry-run=client
# Verify namespace labels kubectl get namespace namespace-name --show-labels ```
Pod Security Standards Levels
| Level | Restrictions | Use Case |
|---|---|---|
| Privileged | None | System components, node agents |
| Baseline | No hostPath, privileged, host networking | Infrastructure pods |
| Restricted | Baseline + non-root, drop caps, seccomp | Application pods |
PSS Violations Quick Reference
| Violation | Restricted Fix | Alternative |
|---|---|---|
| privileged: true | Remove or set false | Use privileged namespace |
| hostPath volume | Use PVC | Use privileged namespace |
| Running as root | runAsNonRoot: true, runAsUser: 1000 | Use baseline namespace |
| No capabilities drop | capabilities: drop: [ALL] | Use baseline namespace |
| No seccomp | seccompProfile: type: RuntimeDefault | Use baseline namespace |
| allowPrivilegeEscalation: true | Set to false | Use baseline namespace |
Prevention Best Practices
Set appropriate PSS level for each namespace. Use restricted level for application workloads. Test pod security compliance with --dry-run. Add securityContext to all pod specs. Use PSA warn mode before enforcing. Document security requirements for applications. Consider OPA/Gatekeeper for advanced policies.
Pod security policy issues are straightforward once you know the enforced level. The warnings from PSA tell you exactly what's wrong, and the fix is adding the appropriate securityContext settings or moving the pod to a namespace with appropriate enforcement level.