Lakshya

Security Engineering · Chapter 7 of 12

Container and Kubernetes security

What a container actually isolates, the four settings that remove most of the risk, and the cluster permissions that are administrator in disguise.

6 min read0 diagramsAll 12 chapters

Container security suffers from a widespread misconception about what a container is, and most of the practical risk comes from four settings people leave at their defaults. This chapter is both.

What a container actually isolates

A container is not a virtual machine. It is a process on the host kernel, with its view of the world constrained by three kernel features:

  • Namespaces control what the process can see — its own process table, network stack, filesystem mounts, users, hostname. This is the isolation people think of when they say container.
  • Control groups limit what it can consume — CPU, memory, I/O. This is resource isolation, not security isolation, though memory limits do prevent one workload starving a node.
  • Capabilities, seccomp and mandatory access control limit what it can do — which privileged operations and which system calls are permitted.
  • And the consequence that follows: the kernel is shared. A kernel vulnerability is a container escape. That is why multi-tenant workloads with genuinely hostile neighbours use hardware virtualisation underneath — lightweight virtual machines or a user-space kernel — rather than relying on namespaces alone.

Four settings that remove most of the practical risk

1 · Do not run as root. Set a non-root user. Combined with any escape primitive, root in the container becomes root on the node. This is the single highest-value change and it is a two-line addition.

2 · Read-only root filesystem. An attacker who cannot write cannot persist, cannot drop a tool, and cannot modify your binary. Mount a writable volume for the specific paths that need one — usually a temporary directory — and nothing else.

3 · Drop all capabilities, add back nothing. Almost no application needs any Linux capability. Dropping all of them removes an entire class of privilege operation, and if something breaks you will find out immediately which one it genuinely needed.

4 · No privilege escalation. Prevents a process gaining more privileges than its parent through setuid binaries.

These four are a short block of configuration and they are the difference between a compromised process and a compromised node. The reason they are frequently missing is not disagreement — it is that the defaults are permissive and nobody changed them. Which is exactly what admission policy is for.

The permissions that are administrator in disguise

Cluster role-based access control looks granular and contains several permissions that are equivalent to full control. These recur in real assessments:

PermissionWhat it actually means
Create podsRun arbitrary code on a node — mount the host filesystem, run privileged, use the node's identity. This is the big one, and 'developers can deploy' usually grants it
Read secrets in a namespaceRead every credential in it. Which is usually the database password, the cloud credential and the signing key
Create a service account tokenImpersonate that identity — a lateral movement primitive that leaves little trace
Create or modify workloads (deployments, jobs, cron jobs)Equivalent to creating pods, one step removed. People restrict pod creation and leave these open
Exec into a podFull access to whatever that pod can reach, with its identity
Modify webhook configurationsIntercept or bypass every admission policy in the cluster — including the ones enforcing everything above
Escalate or bind rolesGrant yourself anything. Usually overlooked because it does not name a resource

The practical audit: list who can create pods, read secrets, and modify webhooks. In most clusters the answer is far more people than anyone expects, usually through a group binding that made sense when the cluster had three services.

The workload identity problem

A pod needs to talk to a cloud service. The historic approach was to give the whole node a cloud identity, which meant every pod on that node inherited it — so a compromised sidecar had the permissions of the most privileged workload sharing its node.

The modern approach federates the pod's own service account identity to the cloud provider, so each workload gets exactly its own permissions and no static credential exists at all. If a cluster still uses node-level cloud identity, that is usually the highest-value finding in an assessment, because it collapses your entire authorisation model down to the most privileged thing on each node.

The related control worth checking: can pods reach the cloud metadata service? If they can, any request-forgery vulnerability in any workload becomes credential theft, as covered in the web vulnerability chapter. Blocking pod access to the metadata endpoint at the network layer is a one-line policy and it removes the chain entirely.

Admission control: policy that cannot be bypassed

Everything above is a setting somebody can forget. Admission control is the mechanism that makes it structural: a policy engine evaluates every object before it is admitted and refuses the ones that violate the rules.

  • Start in audit mode. Run the policies as warnings first and look at what would have been rejected. Turning on enforcement without that step breaks deployments and burns the credibility of the whole programme.
  • Enforce the four settings above, plus image provenance — refuse unsigned images, and refuse tags in favour of digests.
  • Have an exception path with an owner and an expiry. Some workload will genuinely need a capability. A documented, time-limited exception is a control; a blanket namespace exclusion is the absence of one.
  • And protect the webhook configuration itself, because as the table above notes, anyone who can modify it can disable everything.

What runtime detection adds, and what it does not

Everything so far is preventive. Runtime detection watches system calls — usually through kernel-level instrumentation — and alerts on behaviour that should not happen: a shell spawning inside a container, an unexpected outbound connection, a write to a path that should be read-only, a package manager running in production.

It is genuinely valuable and it has the same tuning problem as every detection system: the default rule sets are noisy, and a team that does not invest in tuning will stop reading the alerts within a month. The honest sequencing is preventive controls first, detection second — because a cluster with the four settings enforced generates far fewer runtime alerts worth investigating, and the ones it does generate mean something.

Check yourself

What does a container actually isolate?A process on the shared host kernel, constrained by namespaces (what it sees), control groups (what it consumes) and capabilities and seccomp (what it can do). A kernel vulnerability is an escape.
Which four settings remove most container risk?Non-root user, read-only root filesystem, drop all capabilities, and no privilege escalation. Short configuration, and the difference between a compromised process and a compromised node.
Which cluster permission is administrator in disguise?Creating pods — it means running arbitrary code on a node with the node's identity. Workload objects grant it one step removed, and people restrict pods and forget those.
What is the highest-value finding in most cluster assessments?Node-level cloud identity, which gives every pod on a node the permissions of the most privileged workload sharing it. Federated per-workload identity removes it.
← Two threat models, workedControl frameworks, and what an auditor actually wants →