Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Pod Security Standards (PSS) define three levels of security policies -- Privileged, Baseline, and Restricted -- enforced by the Pod Security Admission (PSA) controller built into Kubernetes 1.25+. PS
.claude/skills/implementing-kubernetes-pod-security-standards/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✓→✓ | = Same ✓ | 335% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 392% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 388% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 277% | 0% |
| case-05 | ✓→✓ | = Same ✓ | 202% | 0% |
Pod Security Standards (PSS) define three levels of security policies -- Privileged, Baseline, and Restricted -- enforced by the Pod Security Admission (PSA) controller built into Kubernetes 1.25+. PSA replaces the deprecated PodSecurityPolicy and provides namespace-level enforcement with three modes: enforce, audit, and warn.
securityContext changesNot this skill: configuring the controller that enforces these profiles — namespace labels, AdmissionConfiguration, exemptions, or debugging a pod PSA rejected. Use implementing-pod-security-admission-controller.
| Profile | Purpose | Restrictions | |---------|---------|-------------| | Privileged | Unrestricted, system workloads | None | | Baseline | Prevents known escalations | No hostNetwork, hostPID, hostIPC, privileged containers, dangerous capabilities | | Restricted | Hardened best practices | Non-root, drop ALL caps, seccomp required, read-only rootfs recommended |
| Mode | Behavior | |------|----------| | enforce | Rejects pods that violate the policy | | audit | Logs violations in audit log but allows pod | | warn | Returns warning to user but allows pod |
yaml# Restricted namespace - production workloads 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
yaml# Baseline namespace - general workloads apiVersion: v1 kind: Namespace metadata: name: staging labels: pod-security.kubernetes.io/enforce: baseline 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
yaml# Privileged namespace - system components only apiVersion: v1 kind: Namespace metadata: name: kube-system labels: pod-security.kubernetes.io/enforce: privileged pod-security.kubernetes.io/enforce-version: latest
bash# Apply restricted enforcement to production kubectl label namespace production \ pod-security.kubernetes.io/enforce=restricted \ pod-security.kubernetes.io/audit=restricted \ pod-security.kubernetes.io/warn=restricted \ --overwrite # Apply baseline to staging with restricted warnings kubectl label namespace staging \ pod-security.kubernetes.io/enforce=baseline \ pod-security.kubernetes.io/audit=restricted \ pod-security.kubernetes.io/warn=restricted \ --overwrite # Check labels on all namespaces kubectl get namespaces -L pod-security.kubernetes.io/enforce
yaml# Restricted-compliant deployment apiVersion: apps/v1 kind: Deployment metadata: name: secure-app namespace: production spec: replicas: 3 selector: matchLabels: app: secure-app template: metadata: labels: app: secure-app spec: automountServiceAccountToken: false securityContext: runAsNonRoot: true runAsUser: 65534 runAsGroup: 65534 fsGroup: 65534 seccompProfile: type: RuntimeDefault containers: - name: app image: myregistry.com/myapp:v1.0.0@sha256:abc123 ports: - containerPort: 8080 protocol: TCP securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: - ALL runAsNonRoot: true runAsUser: 65534 resources: requests: memory: "64Mi" cpu: "100m" limits: memory: "256Mi" cpu: "500m" volumeMounts: - name: tmp mountPath: /tmp - name: cache mountPath: /var/cache volumes: - name: tmp emptyDir: sizeLimit: 100Mi - name: cache emptyDir: sizeLimit: 50Mi
bash# Phase 1: Audit mode - discover violations without blocking kubectl label namespace my-namespace \ pod-security.kubernetes.io/audit=restricted \ pod-security.kubernetes.io/warn=restricted # Check audit logs for violations kubectl logs -n kube-system -l component=kube-apiserver | grep "pod-security" # Phase 2: Enforce baseline, warn on restricted kubectl label namespace my-namespace \ pod-security.kubernetes.io/enforce=baseline \ pod-security.kubernetes.io/warn=restricted \ --overwrite # Phase 3: Full restricted enforcement kubectl label namespace my-namespace \ pod-security.kubernetes.io/enforce=restricted \ --overwrite
bash# Test what would happen with restricted enforcement kubectl label --dry-run=server --overwrite namespace my-namespace \ pod-security.kubernetes.io/enforce=restricted # Example output: # Warning: existing pods in namespace "my-namespace" violate the new # PodSecurity enforce level "restricted:latest" # Warning: nginx-xxx: allowPrivilegeEscalation != false, # unrestricted capabilities, runAsNonRoot != true, seccompProfile
| Control | Restricted | Requirement | |---------|-----------|-------------| | HostProcess | Must not set | Pods cannot use Windows HostProcess | | Host Namespaces | Must not set | No hostNetwork, hostPID, hostIPC | | Privileged | Must not set | No privileged: true | | Capabilities | Baseline list only | Only NET_BIND_SERVICE, drop ALL for restricted | | HostPath Volumes | Must not use | No hostPath volume mounts | | Host Ports | Must not use | No hostPort in container spec | | AppArmor | Default/runtime | Cannot set to unconfined | | SELinux | Limited types | Only container_t, container_init_t, container_kvm_t | | /proc Mount Type | Default only | Must use Default proc mount | | Seccomp | RuntimeDefault or Localhost | Must specify seccomp profile (restricted) | | Sysctls | Safe set only | Limited to safe sysctls |
bash# Verify namespace labels kubectl get ns --show-labels | grep pod-security # Test pod creation against policy kubectl run test-pod --image=nginx --namespace=production --dry-run=server # Check for violations in audit logs kubectl get events --field-selector reason=FailedCreate -A # Scan with Kubescape for PSS compliance kubescape scan framework nsa --namespace production
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | pass→pass | 8,837 | 9,385 | +6% | 1 | 1 | 0% | 660 | 2,870 | +335% | 0 | 0 | — |
case-02 | pass→pass | 8,533 | 10,121 | +19% | 1 | 1 | 0% | 612 | 3,012 | +392% | 0 | 0 | — |
case-03 | pass→pass | 8,500 | 8,303 | -2% | 1 | 1 | 0% | 516 | 2,520 | +388% | 0 | 0 | — |
case-04 | pass→pass | 8,823 | 8,597 | -3% | 1 | 1 | 0% | 724 | 2,729 | +277% | 0 | 0 | — |
case-05 | pass→pass | 9,708 | 8,411 | -13% | 1 | 1 | 0% | 869 | 2,628 | +202% | 0 | 0 | — |
case-06 | pass→pass | 14,691 | 9,570 | -35% | 1 | 1 | 0% | 1,818 | 2,857 | +57% | 0 | 0 | — |
case-07 | pass→pass | 9,932 | 8,363 | -16% | 1 | 1 | 0% | 819 | 2,650 | +224% | 0 | 0 | — |
case-08 | pass→pass | 10,050 | 9,520 | -5% | 1 | 1 | 0% | 877 | 2,893 | +230% | 0 | 0 | — |
case-09 | fail→fail | 16,813 | 15,862 | -6% | 1 | 1 | 0% | 2,193 | 4,070 | +86% | 0 | 0 | — |
case-10 | pass→pass | 28,165 | 10,324 | -63% | 1 | 1 | 0% | 1,566 | 3,082 | +97% | 0 | 0 | — |
case-11 | pass→pass | 16,566 | 14,475 | -13% | 1 | 1 | 0% | 2,329 | 4,023 | +73% | 0 | 0 | — |
case-12 | pass→pass | 9,899 | 11,703 | +18% | 1 | 1 | 0% | 895 | 3,295 | +268% | 0 | 0 | — |
case-13 | pass→pass | 19,040 | 17,342 | -9% | 1 | 1 | 0% | 2,633 | 4,323 | +64% | 0 | 0 | — |
case-14 | pass→pass | 15,734 | 12,121 | -23% | 1 | 1 | 0% | 1,992 | 3,247 | +63% | 0 | 0 | — |
case-15 | fail→fail | 13,260 | 10,883 | -18% | 1 | 1 | 0% | 1,723 | 3,228 | +87% | 0 | 0 | — |
case-16 | fail→fail | 23,211 | 23,181 | -0% | 1 | 1 | 0% | 3,276 | 5,463 | +67% | 0 | 0 | — |
case-17 | fail→fail | 13,139 | 10,758 | -18% | 1 | 1 | 0% | 1,569 | 4,151 | +165% | 0 | 0 | — |
case-18 | pass→pass | 15,166 | 13,711 | -10% | 1 | 1 | 0% | 2,623 | 4,546 | +73% | 0 | 0 | — |
case-19 | pass→pass | 4,983 | 8,351 | +68% | 1 | 1 | 0% | 1,001 | 2,734 | +173% | 0 | 0 | — |
case-20 | pass→pass | 10,314 | 9,521 | -8% | 1 | 1 | 0% | 1,033 | 2,831 | +174% | 0 | 0 | — |
case-21 | pass→pass | 16,207 | 9,141 | -44% | 1 | 1 | 0% | 2,075 | 3,767 | +82% | 0 | 0 | — |
case-22 | pass→pass | 10,807 | 5,716 | -47% | 1 | 1 | 0% | 1,102 | 3,053 | +177% | 0 | 0 | — |
case-23 | pass→pass | 16,090 | 13,605 | -15% | 1 | 1 | 0% | 3,049 | 3,680 | +21% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of 0 percentage points is the difference between those two pass rates over the 23 comparable cases.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 7/28/2026 | — |
Other measured skills in the registry, with their headline benchmark lift.