Home › CKS › Topics › Practice tasks › Pod Security Standards
CKS · Minimize Microservice Vulnerabilities

Make a Deployment Pass the Restricted Pod Security Standard

Namespace restricted-ns enforces the restricted Pod Security Standard. A Deployment pss-app in this namespace is currently non-compliant and its Pods cannot start.

Check live lab access → All CKS tasks

Live lab access

This task description is public. Live practice requires full access unless this is the selected free weekly task. AI Lab Coach is available in single-task labs, including the free weekly task. See this week's free task.

Create an account to continue →

Read this week's free task →

On a phone? Read the task and create your account here, then sign in on a desktop or laptop for the terminal lab. Nothing starts until you choose Start.

The task

Task

Namespace restricted-ns enforces the restricted Pod Security Standard.

A Deployment pss-app in this namespace is currently non-compliant and its Pods cannot start.

Requirements

Update the Deployment so that its Pods comply with the restricted Pod Security Standard.

Ensure the Pods run successfully in the restricted namespace.

Original Prepium guide · Written for Kubernetes v1.35 and checked against the official documentation on 6 October 2026. Use a disposable practice cluster.

Read a Pod Security rejection and satisfy the restricted profile

The Pod Security Standards define three profiles: privileged (no restrictions), baseline (blocks known privilege escalations such as privileged containers, host namespaces and hostPath) and restricted (baseline plus current hardening practice). The built-in Pod Security Admission controller applies them per namespace, driven by labels. In the exam the namespace is usually already labelled; your job is to read why Pods are refused and change exactly the fields that the profile checks.

namespace labels
  pod-security.kubernetes.io/enforce=restricted   → violating Pods are rejected
  pod-security.kubernetes.io/warn=restricted      → client sees a warning, object allowed
  pod-security.kubernetes.io/audit=restricted     → audit log annotation, object allowed
  pod-security.kubernetes.io/<mode>-version=v1.35 → pin the rules to a release (or latest)

1. Label a namespace and break a Deployment on purpose

kubectl create namespace prepium-tutorial
kubectl label --overwrite ns prepium-tutorial \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/enforce-version=v1.35 \
  pod-security.kubernetes.io/warn=restricted \
  pod-security.kubernetes.io/warn-version=v1.35
kubectl -n prepium-tutorial create deployment ticker --image=busybox:1.36 -- sleep 3600
kubectl -n prepium-tutorial get deploy,rs,pods

The Deployment is created, and because of the warn label kubectl prints a warning first. Enforcement is applied only to Pods, never to the Deployment or ReplicaSet, so the ReplicaSet exists but no Pod appears. Without a warn label you would get no hint at apply time and would have to read kubectl describe rs events to find the refusal.

2. Turn the message into a checklist

The warning has a documented shape: would violate PodSecurity "restricted:<version>": followed by one entry per failed check, each naming the container and the field it must set. For a stock busybox container you should see four entries, and each maps to one field:

allowPrivilegeEscalation != false   → containers[*].securityContext.allowPrivilegeEscalation: false
unrestricted capabilities           → containers[*].securityContext.capabilities.drop: ["ALL"]
runAsNonRoot != true                → runAsNonRoot: true (Pod level covers every container)
seccompProfile                      → seccompProfile.type: RuntimeDefault (or Localhost)

Restricted also forbids runAsUser: 0, allows adding back only NET_BIND_SERVICE, limits volumes to types such as configMap, secret, emptyDir, projected and persistentVolumeClaim, and inherits every baseline rule. A real workload may trip several of these at once; fix them all, then re-read the message.

3. Apply the fields where they belong

Run kubectl -n prepium-tutorial edit deployment ticker and give the Pod template this shape:

    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 10001
        seccompProfile:
          type: RuntimeDefault
      containers:
      - name: busybox          # keep the existing container name
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop: ["ALL"]

Pod-level runAsNonRoot and seccompProfile satisfy the check for every container; capabilities and escalation exist only per container, including init containers. The explicit non-zero runAsUser matters for a different reason: admission only checks fields, but the kubelet verifies runAsNonRoot at start time. busybox runs as root by default, so without a UID the Pod would be admitted and then its container would refuse to start.

4. Confirm

kubectl -n prepium-tutorial rollout status deployment/ticker
kubectl -n prepium-tutorial get pods
kubectl label --dry-run=server --overwrite ns prepium-tutorial \
  pod-security.kubernetes.io/enforce-version=latest

Changing an enforce label, even in a server-side dry run, makes the admission plugin test every existing Pod in the namespace against the new setting and report violations as warnings. Here it asks whether your Pods would also pass the newest version of the profile; no warnings means they would.

Common mistakes

Example checkEvidence
Namespace policy unchangedpod-security.kubernetes.io/enforce=restricted still on the namespace
Template compliantNo warning when the Deployment is re-applied
Pods admittedNew ReplicaSet has Pods; no FailedCreate events
Pods actually runReady Pods, container not stuck on the non-root check

Cleanup: kubectl delete namespace prepium-tutorial. References: Pod Security Standards, Pod Security Admission, Enforce Pod Security Standards with namespace labels. Next, try immutable containers or Pod versus container securityContext.

Exam
CKS
Domain
Minimize Microservice Vulnerabilities
Grading
Programmatic · partial credit

What this tests

Apply Pod Security Standards, securityContext, and mTLS, and protect secrets at rest. On the CKS exam, Minimize Microservice Vulnerabilities tasks are graded purely on what you build in the cluster - not multiple choice - so the only way to get faster is to do them on a real cluster against a clock.

Practice it for real

The public description lets you study the task before signing up. Full access includes this live lab; the selected Task of the Week is free with an account. You solve the task in a real terminal, hit validate, and a programmatic checker scores exactly what you got right and wrong (with partial credit). You can open the solution while practising, then retry and use the failed checks to improve your score.

Related CKS tasks