19 hands-on labs to practise for the Certified Kubernetes Security Specialist, roughly 8 hours of work, each one graded on the state of your machine rather than on the commands you typed. They run on your own hardware with the `dsoxlab` command line, and cost nothing.
Securing the cluster and what runs on it: hardening, admission, network policies, image supply chain and runtime detection. The CKA is its prerequisite.
- 19labs
- 8hours of practice
- 19on real VMs
Levels 9 intermediate 10 advanced
Official exam objectives published by CNCF
These are not exam questions. They are hands-on exercises on the skills the exam measures, graded on the state of your machine.
Kubernetes, CKA, CKAD and CKS
Add this catalogue dsoxlab catalog add https://github.com/stephrobert/kubernetes-dsoxlab-training
CKS, Certified Kubernetes Security Specialist
-
Confine a Pod with an AppArmor profile
Load an AppArmor profile on the node, apply it to a container through the securityContext field, and prove that the confinement holds by watching a write the profile forbids fail.
dsoxlab start cks-apparmor-confiner-un-pod -
Deny a system call to a container, and prove it from the inside
A container that may call anything the kernel offers. Write a seccomp profile that refuses one family of system calls, apply it, and prove the confinement holds: the forbidden call fails from inside, and everything else still works.
dsoxlab start cks-seccomp-profile -
Reject a privileged Pod at admission, with Pod Security Admission
A namespace that accepts anything, including a Pod that shares the host's PID namespace and runs as root. Turn on the restricted standard so the cluster refuses it at admission, and prove the refusal without creating anything: a server-side dry run goes through admission and writes nothing.
dsoxlab start cks-pod-security-admission -
Take over a privileged Pod in production, without stopping its work
A Pod runs with the host's process namespace, as root, privileged, from a floating tag. Rebuild it without any of that, and prove the difference where it is visible: from inside, the container no longer sees the host.
dsoxlab start cks-secure-existing-pod -
Make a container immutable without bringing it down
A running Deployment can still be written to from the inside. Make its root filesystem read-only, drop every capability, forbid escalation, and keep the application serving: nginx needs a few writable paths, and finding them is the exercise.
dsoxlab start cks-security-context-immutable -
Isolate a Pod from the host kernel, and prove it by reading its version
The node offers a second container runtime that runs an application kernel of its own. Put a Pod inside it, and prove the isolation the only way that cannot be faked: from inside, the kernel version is no longer the node's.
dsoxlab start cks-runtime-sandbox-gvisor -
Pin an image by digest, and prove the tag is not enough
A Deployment that trusts a mutable tag. Pin it to the immutable digest of the image it actually runs, and prove the pin holds: the declared digest must match what the runtime resolved, not just look like one.
dsoxlab start cks-image-pinned-digest -
Have the cluster itself reject an unpinned image, with no webhook
A namespace accepts any image, tag and all. Make the API server refuse the ones that are not pinned by digest, with a policy it evaluates itself: no webhook, no controller, nothing to keep running.
dsoxlab start cks-validating-admission-policy -
Replace an image riddled with flaws, and prove it with a second scan
A Deployment runs an image three years old. Scan it, pick a replacement, and prove the choice: the test scans both and demands strictly fewer critical findings than the original, which no fixed threshold could measure honestly.
dsoxlab start cks-image-scanning-trivy -
Sign an image, and prove the signature by having another one refused
A local registry holds two images, neither signed. Sign one with cosign, publish the public key, and prove the chain works: the same key must accept the signed image and refuse the other. A verification that accepts everything proves nothing.
dsoxlab start cks-cosign-verify-image -
Fix a Dockerfile static analysis refuses, without changing the application
A Dockerfile that builds and runs, and that static analysis rejects on five counts. Fix them all without changing what the image does, and prove it by running the analysis again: the five findings must be gone by their identifiers, not by a count that a new rule would break.
dsoxlab start cks-dockerfile-static-analysis -
Take cluster-admin away from a service account, without stopping its work
A ServiceAccount holds cluster-admin because it was quicker. Take that power back and give it exactly what its application needs, no more. The proof is not the manifest: it is what the API server answers when that account asks.
dsoxlab start cks-rbac-least-privilege -
Close the API server profiler, without closing the API
The API server exposes its Go profiler to anyone who can reach it, and a kubeadm cluster leaves it on. Close it and raise the TLS floor, then prove both halves: the profiler answers 404, and the cluster still works.
dsoxlab start cks-api-server-hardening -
Record who reads Secrets, and only the metadata of everything else
The cluster keeps no trace of who reads what. Give the API server an audit policy with two levels, full bodies for Secrets and metadata for everything else, and prove it works by reading the log the cluster has just written.
dsoxlab start cks-audit-log-policy -
Deny everything, then reopen the strict minimum, DNS included
A namespace where everything talks to everything. Close it completely in both directions, then reopen exactly two things: the one flow the application needs, and name resolution, which a default-deny egress breaks in a way nothing warns you about.
dsoxlab start cks-networkpolicy-default-deny -
Require mTLS in a mesh, and prove it with a client left outside
A service mesh accepts plain traffic from anyone, inside the mesh or out. Require mutual TLS, and prove it the only way that counts: a Pod with a sidecar still reaches the service, a Pod without one no longer does.
dsoxlab start cks-istio-mtls-lockdown -
Serve a site over HTTPS with its own certificate, not the controller's
The site already answers over HTTPS, which is exactly the trap: the Ingress controller serves its own default certificate to anyone who asks. Terminate TLS with a certificate that actually names the host.
dsoxlab start cks-ingress-tls -
Bring down a CIS audit count, and prove it with a second audit
kube-bench audits the control plane against the CIS benchmark and fails ten checks on a stock kubeadm cluster. Fix the three that share one cause, then prove it the only honest way: run the audit again and count.
dsoxlab start cks-cis-benchmark-remediate -
Capstone: open an enclave for a team you do not trust
An outside team needs room in your cluster. Give them one that stays safe even if they are not: the cluster itself must refuse what they should not deploy, their identity must be able to do almost nothing, and nothing outside the enclave may reach what runs inside it.
dsoxlab start cks-capstone-enclave