# Defense in Depth & the Kubernetes Security Model ## Security is a posture, not a single setting There is no single "make it secure" switch in Kubernetes. Real security comes from **defense in depth** — multiple independent layers, each reducing what an attacker (or a bug) can do if an earlier layer fails. If a container has a vulnerability that lets an attacker execute arbitrary code, the question that actually matters is: what can that code DO once it's running? A container running as root, with every Linux capability, on a writable filesystem, with no restrictions at all, can do far more damage than one deliberately hardened to need almost nothing. ## Least privilege: grant only what's actually needed The organizing principle behind everything in this course is **least privilege**: a workload should have exactly the permissions and capabilities it needs to do its job, and nothing more. This sounds obvious stated plainly, but the DEFAULT behavior of a plain container is closer to "maximum privilege unless told otherwise" — root user, all standard Linux capabilities, a writable filesystem. Hardening a Pod means deliberately narrowing that down. ## SecurityContext: where you actually configure this `securityContext` (settable at the Pod level and per-container) is where you declare these restrictions: ```yaml spec: securityContext: runAsNonRoot: true runAsUser: 1000 containers: - name: app securityContext: readOnlyRootFilesystem: true capabilities: drop: ["ALL"] ``` - **`runAsNonRoot` / `runAsUser`** — the container process runs as a specific non-root user instead of root. If a container image was built to require root and you set this, it will fail to start — which is a good, loud failure, not a silent security gap. Hardening sometimes surfaces an image's OWN bad assumptions. - **`capabilities: drop: ["ALL"]`** — Linux capabilities are fine-grained permissions (`NET_BIND_SERVICE`, `SYS_ADMIN`, dozens more) a process can hold even without full root. Dropping all of them, then adding back only the specific ones actually needed, is the least-privilege pattern applied to capabilities specifically. - **`readOnlyRootFilesystem: true`** — the container's own filesystem cannot be written to at all (use an explicit `emptyDir` volume, ROOT 08, for anything that genuinely needs to write temporary files). This closes off a whole category of attack that relies on writing a malicious file to disk. ## Why this matters even when "nothing is currently wrong" None of these settings fix a bug or a vulnerability — they limit the BLAST RADIUS if one exists that you don't yet know about. A container hardened with non-root, dropped capabilities, and a read-only filesystem gives a successful exploit dramatically less to work with than an unhardened one, even against the exact same vulnerability. This is the entire point of defense in depth: you don't rely on any single layer being perfect. ## Instructor Notes **Approximate timing:** 15 minutes read; 10-12 minutes live with the demonstration. **Demo plan:** Have the demonstration activity ready to run right after this lesson — seeing a concrete before/after Pod definition lands the abstract "least privilege" principle far better than the lesson text alone. **Likely misconceptions to watch for:** - Students sometimes think hardening settings are only relevant "if you expect to be attacked." Reframe: defense in depth assumes SOMETHING will eventually go wrong somewhere (a vulnerability, a bug, a misconfiguration) and prepares for that, rather than betting everything on nothing ever going wrong. - `runAsNonRoot: true` failing a Pod's startup is sometimes read as "the security setting is broken." It's the opposite — it's correctly refusing to let a root-requiring image start, which is valuable, actionable information about the image itself. **Discussion question:** "If dropping all capabilities breaks a container that turns out to genuinely need one specific capability, what's the right fix — removing the drop, or something more targeted?" (Answer: add back only that ONE specific capability rather than removing the blanket drop — least privilege means "exactly what's needed," not "give up and grant everything again.") **Optional extension:** ask students to identify one setting from this lesson that would have made zero difference against a vulnerability that lets an attacker read environment variables (a good check that they understand these are layered, not universal, protections — the answer is that none of SecurityContext's settings here directly protect secrets stored in env vars; that's a different concern, covered later in this course).