Lock it down: least-privilege RBAC, hardened pods, network policy
Continues from the last build: Storefront now has durable state, but its pods run as root, its RBAC is wide open, and any pod can reach any other pod.
Storefront works, and that is exactly the problem. It runs on Kubernetes defaults, which means every container starts as root with a full Linux capability set, every workload uses the namespace’s default ServiceAccount that can be widened to anything, and the cluster’s flat network lets any pod open a socket to any other pod.
What you'll build
A Storefront namespace where pods run as a non-root user with a read-only root filesystem, dropped capabilities, and a seccomp profile; where a dedicated ServiceAccount is bound to a least-privilege Role (no cluster-admin, no wildcard verbs); and where a default-deny NetworkPolicy plus explicit allowlists mean each service can reach only the peers it actually needs, all proven by a request that is allowed and a request that is blocked.
See how we teach, before you sign up
You don't just get code dumped on you. Every starter file and every solution is explained line-by-line, in plain English. Here's one real file from this project:
apiVersion: apps/v1
kind: Deployment
metadata:
name: catalog
namespace: storefront
labels:
app: catalog
spec:
replicas: 2
selector:
matchLabels:
app: catalog
template:
metadata:
labels:
app: catalog
spec:
# no securityContext yet -> runs as root
# no serviceAccountName yet -> uses the default SA
containers:
- name: catalog
image: ghcr.io/your-org/catalog:2.0.0
ports:
- containerPort: 8080Reading this file
kind: DeploymentA Deployment keeps the catalog pods running, today it inherits every insecure cluster default because nothing overrides them.image: ghcr.io/your-org/catalog:2.0.0The catalog image, by default its process runs as UID 0 (root) inside the container unless you say otherwise.containerPort: 8080The port the catalog serves on, you will later allow only the gateway to reach this port.
The catalog deployment as it runs today: no securityContext, default ServiceAccount, nothing stopping it talking to anything.
That's 1 of 8 explained code blocks in this single project.
The build, milestone by milestone
- 1
Threat-model the namespace before you touch a control
5 guided stepsHardening without a model is how you both over-restrict (break the app) and under-restrict (miss the real path). Knowing who runs as what, who can call the API, and who talks to whom turns the next three milestones into filling in a plan rather than guessing.
- 2
Harden the pods: non-root, read-only, no capabilities
6 guided stepsA root container with a writable filesystem and full capabilities is a single dependency CVE away from a full host foothold. Non-root plus read-only plus dropped caps removes most of an attacker’s post-exploitation toolkit, this is the highest-leverage control on the rung.
- 3
Give each workload a least-privilege identity
6 guided stepsThe default ServiceAccount is shared and easy to over-grant, and a token that can list secrets or create pods turns a single compromise into lateral movement across the namespace. A dedicated SA with a tight Role means a stolen token can do almost nothing.
- 4
Default-deny the network, then allow only Storefront flows
6 guided stepsA flat cluster network means one compromised pod can scan and reach every other pod, including the database and the API server. Default-deny plus an explicit allowlist turns the network into a least-privilege surface where lateral movement has to be specifically permitted.
- 5
Prove the hardening with allowed-vs-blocked tests
5 guided stepsA control you have not tested is a control you do not have. Hardening that quietly breaks the app gets reverted, and hardening with a gap gives false confidence, only an allowed-vs-blocked pair proves both that the app works and that the attack path is closed.
What's inside when you start
You'll walk away with
This is portfolio-grade. Build it free.
Sign up to unlock every milestone step-by-step, the code skeletons, full reference solutions, and checkable tasks, with your progress saved as you build.
Start building