Home › CKS › Topics › Practice tasks › Dockerfile & Manifest Security
CKS · Supply Chain Security

Fix the Security Flaws in a Dockerfile and a Manifest

Analyze and edit the Dockerfile located at /home/candidate/subtle-bee/build/Dockerfile, fixing one instruction present in the file that is a prominent security/best-practice issue.

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

Analyze and edit the Dockerfile located at /home/candidate/subtle-bee/build/Dockerfile, fixing one instruction present in the file that is a prominent security/best-practice issue.

> Do not add or remove instructions; only modify the one existing instruction with a security/best-practice concern.

> Do not build the Dockerfile. Failure to do so may result in running out of storage and a zero score.

Analyze and edit the given manifest file /home/candidate/subtle-bee/deployment.yaml, fixing one field present in the file that is a prominent security/best-practice issue.

> Do not add or remove fields; only modify the one existing field with a security/best-practice concern.

> Should you need an unprivileged user for any of the tasks, use user nobody with user ID 65535.

Original Prepium guide · Written for Kubernetes v1.35 and checked against the official documentation on 6 October 2026. Use a disposable practice cluster. The Dockerfile and manifest below are invented for this guide; review them by reading, no build needed.

Spot the risky line: image and Pod security review

CKS review tasks hand you a Dockerfile or a manifest and ask you to find the line that hurts security. The skill is reading quickly with a checklist: which user the process runs as, which base image you will really get, what ends up inside image layers, and which privileges the Pod spec adds on top. The image and the manifest are linked: if the Pod does not set runAsUser, Kubernetes uses the user from the image metadata, which comes from USER.

Dockerfile USER ──→ image metadata user ──→ container UID (unless securityContext.runAsUser overrides)
FROM tag ──→ may move     FROM tag@digest ──→ fixed      ENV/ARG ──→ stays in image

1. Read a Dockerfile with four questions

FROM node:latest
ENV REGISTRY_TOKEN=tok_live_example
WORKDIR /srv/invoice
COPY . .
RUN npm ci
CMD ["node", "server.js"]

2. The same Dockerfile, reviewed

FROM node:22-alpine@sha256:<digest-you-verified>
WORKDIR /srv/invoice
COPY package*.json ./
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc npm ci
COPY . .
USER 10001:10001
CMD ["node", "server.js"]

The secret mount exposes the token only while that one RUN executes, so it never lands in a layer. USER accepts a name or UID with an optional group or GID; set the group explicitly, because a user without a primary group runs with the root group. On the exam, edit only what you are asked to and do not build if the brief says not to.

3. Read the Pod spec with the same eye

    securityContext:
      privileged: true                 # near-root on the host
      allowPrivilegeEscalation: true   # setuid binaries can raise privileges
      runAsUser: 0                     # overrides the image's USER with root

A privileged container is, per the API reference, essentially equivalent to root on the host. allowPrivilegeEscalation controls the no_new_privs flag, and it is always true for a privileged container or one with CAP_SYS_ADMIN, so setting it to false alone does not help while privileged stays true. A hardened version sets runAsNonRoot: true, a non-zero runAsUser, allowPrivilegeEscalation: false and drops all capabilities.

4. Let the cluster grade your manifest

kubectl create namespace prepium-tutorial
kubectl label namespace prepium-tutorial pod-security.kubernetes.io/warn=restricted
kubectl -n prepium-tutorial apply -f invoice-deployment.yaml

Warn mode is applied to Deployments too, so kubectl prints every Restricted-profile violation (privileged, privilege escalation, running as root) without blocking anything. When a Pod does run, kubectl exec into it and run id to see the real UID.

Common mistakes

Example checkEvidence
Image runs unprivilegedUSER names a non-root user or UID
Base image reproducibleFROM has a specific tag, ideally a digest
No secrets in layersNo tokens in ENV/ARG; build secrets via mounts
Pod adds no privilegesNo privileged: true, escalation false, UID not 0; no PSA warnings

Cleanup: kubectl delete namespace prepium-tutorial. References: Docker build best practices, Build secrets, Configure a Security Context, Pod Security Standards. Next, try Pod Security Standards or CKAD security contexts.

Exam
CKS
Domain
Supply Chain Security
Grading
Programmatic · partial credit

What this tests

Scan images for vulnerabilities, harden Dockerfiles, generate SBOMs, and enforce image policy. On the CKS exam, Supply Chain Security 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