Threat Model & Philosophy

Before you defend something, you have to be honest about who you’re defending against — and what you’re willing to lose.

Security isn’t a product you install; it’s a set of bets about who will attack you, how, and what happens when one of your defenses fails. This chapter states those bets plainly. Every later decision in this guide traces back to something here. If you only read one page of theory, read this one.

The core philosophy: assume breach

Most home setups are built on hope — “nobody will bother attacking me.” That is not a security model. This guide is built on the opposite assumption:

Assume every layer will eventually be breached, and design so that a breach of one layer is contained by the next. We never rely on a single wall. We build seven, each independent, so that defeating one buys an attacker almost nothing.

Important

Imagine a bank. The cash isn’t protected by one locked door — it’s a locked building, inside it a locked vault room, inside that a vault, inside that a safe-deposit box. A thief who picks the front door is still standing in a hallway. We’re building the same thing for your computer.

In plain English

This is called defense-in-depth, and it has a measurable payoff: the chance an attacker defeats every independent layer is the product of defeating each one. Ten percent times ten percent times ten percent gets very small, very fast.

Who we’re defending against

We design for four realistic adversaries, from most to least likely.

Adversary What they want Their typical move
Automated bots Any exposed service to hijack (crypto-mining, botnets) Mass-scan the internet for open ports & known bugs
A compromised container image To run their code on your hardware You pull a poisoned image; it tries to escape the container
A vulnerable app you deployed A foothold to pivot deeper Exploit your app, then attack the cluster from inside
Someone with physical access The data on the disk Steal the machine or the USB drive and read it elsewhere

We are not trying to stop a nation-state with unlimited budget and physical access to your running, unlocked machine. That’s an honest boundary, not a weakness — see “What’s out of scope” below. Everything short of that, we defend against hard.

Note

The trust boundaries (where the walls are)

A trust boundary is a line where data or control passes from something less trusted to something more trusted. Every boundary is a place to put a guard.

ATTACKER Firewall L0 · nftables VM wall L1 · KVM/sVirt Sandbox L3 · gVisor Default-deny L4 · Cilium Encryption L5 · LUKS2 Admission ✦ Kyverno L6 · always watching CORE
Each ring is a trust boundary an attacker must cross. The arrows show where guards are posted.
  1. Internet → Host. The host firewall (nftables) drops everything except one WireGuard port. There is no open SSH, no open Kubernetes API, nothing to scan.
  2. Host → VM. k3s runs inside a virtual machine. A Kubernetes compromise is trapped in a disposable VM that can’t see the host’s secrets.
  3. VM → Pod. Each pod runs in a sandbox (gVisor/Kata) with dropped privileges, a read-only filesystem, and its own user namespace. A breakout hits a wall.
  4. Pod → Pod. The network denies all traffic by default; pods can only reach what you’ve explicitly allowed, and every packet between them is encrypted.
  5. Anything → Disk. Every byte at rest — the OS, the container layers, the object store, the volumes — is encrypted with LUKS2. A stolen drive is noise.
  6. Anything → Cluster control. Only signed, scanned images run. Only an authenticated admin over WireGuard can issue commands, and every command is logged immutably.

How each layer maps to a threat

If an attacker… …they are stopped/contained by
Scans your IP for open ports L0 host firewall (default-deny, only WireGuard open)
Breaks Kubernetes itself L1 immutable VM isolates them from the host
Escapes a container L3 sandbox + dropped caps + user namespaces wall them in
Tries to spread to other pods L4 default-deny network policy blocks lateral movement
Steals the machine or USB drive L5 LUKS2 encryption makes the data unreadable
Sneaks in a malicious image image signing + admission control refuses to run it
Quietly does damage from inside L6 eBPF runtime sensor detects & can kill it in real time
Tampers with the running OS L1 immutable, read-only root with dm-verity rejects changes

Notice that no single failure is fatal. Every row above is backed by at least one other layer. That redundancy is the entire point.

Hardened

The assume-breach mindset in practice

Three habits follow from “assume breach”, and the whole architecture enforces them:

  • Least privilege everywhere. Nothing gets a permission it doesn’t strictly need — not a pod, not a service account, not a network connection, not you.
  • Everything is logged. If you can’t see it, you can’t defend it. Layer 6 records metrics, logs, and kernel-level events continuously, and alerts on the ones that matter.
  • Recoverable by design. Because the OS is immutable and the config is in Git, a compromised node is not a crisis — you wipe it and rebuild from scratch in minutes. We treat machines as cattle, not pets.

What’s out of scope (the honest part)

A guide that claims to stop everything is lying. Here is what this design does not fully solve, stated plainly so you can make your own call:

  • A running machine with the disk already unlocked. Encryption protects data at rest. If an attacker has root on the live, booted host, they’re inside the walls. Physical security of the powered-on machine is on you.
  • A backdoor in the silicon or firmware. We harden the firmware we can reach; we can’t audit the CPU’s microcode. Measured boot detects tampering it can see.
  • Your own mistakes. If you paste a malicious script as root, or hand out your WireGuard key, no architecture saves you. The guide minimizes how often you must act as root, but discipline is still required.
  • Zero-day bugs in the tools themselves. We reduce the blast radius (sandbox, network policy, immutability) so one unknown bug rarely reaches the core — but “rarely” is not “never.”
Warning

This is not hedging — it’s the map of where the walls end, so you know exactly what you’re trusting.

What this chapter bought you

You now know the four adversaries, the six trust boundaries, and the single idea that drives every command in this guide: assume breach, contain blast radius, log everything, rebuild fearlessly. Next we turn this philosophy into a concrete architecture you can see and build.