Skip to content
Paul Marinos
Menu

Workload & Container Security

Minimal images and admission control, the Kubernetes hardening that actually contains a compromise, and the shared-responsibility line for serverless and managed services.

Workload security is where the application meets the substrate, and the division of labour is the thing to get right first. The container image is an AppSec artifact built in the pipeline; the runtime that schedules and isolates it is infrastructure. This page is the runtime side — how the platform contains a workload that turns out to be compromised.

The image arrives from the build pipeline, but the runtime decides whether to trust it. Two controls sit at that boundary:

  • Minimal base images. Most vulnerabilities in a scanned image come from the base OS, not your code. Distroless or minimal images carry less to be vulnerable and less for an intruder to use post-compromise — no shell to drop into, no package manager to pull tools with. A smaller image is a smaller attack surface in the most literal sense.
  • Admission control. The cluster gate that refuses an image failing policy — unsigned, unscanned, from an untrusted registry, or running as root. OPA/Gatekeeper and Kyverno enforce it at deploy time, which is where image provenance stops being advisory and becomes a wall: the cluster won’t run what it can’t verify.

Kubernetes is an environment inside the environment, and its defaults favour convenience over containment. The hardening that matters, roughly in order of how often it’s missing:

  • Pod Security Standards. Kubernetes’ built-in mechanism to stop pods running privileged, mounting the host filesystem, or using host networking. The baseline and restricted profiles exist because those capabilities are exactly the pod-escape primitives — a privileged container is one step from the node.
  • Network policy. Pods can reach every other pod by default. Network policies are microsegmentation inside the cluster, and without them a single compromised pod has free east-west movement across the whole cluster.
  • RBAC and namespace design. Service account tokens are mounted into pods by default, and an over-privileged one is cluster access from a compromised container. Scope tightly, disable automounting where not needed, and design namespaces as isolation boundaries rather than just labels.
  • Secrets handling. Kubernetes Secrets are base64, not encrypted, without extra configuration. Enable encryption at rest and prefer an external secrets store for anything sensitive.

The through-line: assume a container will be compromised, and harden so that compromising one doesn’t yield the node or the cluster. Every item above is about containing the blast radius of a workload you’ve already lost.

Beyond configuration, runtime security watches workloads executing — a container suddenly spawning a shell, making unexpected outbound connections, or writing to paths it never touches. This is detection pointed at the workload layer, and its signal is strong for the same reason process lineage is strong in forensics: containers have narrow, predictable behaviour, so deviation is meaningful.

Isolation is the harder-edged version of the same concern: how strong is the boundary between a container and its host, and between tenants? Standard container isolation is a shared kernel, which is a softer boundary than a VM. For genuinely untrusted or multi-tenant workloads, stronger isolation (microVMs, sandboxed runtimes) is the honest answer — a shared kernel is a single escape away from co-tenancy becoming co-location.

Serverless and managed services: the responsibility line

Section titled “Serverless and managed services: the responsibility line”

The shared responsibility model shifts with every step up the abstraction ladder, and the most common serverless mistake is misjudging where the line sits.

  • The provider handles the host, the OS patching, and the runtime for serverless and managed services. Real security you get for free.
  • You still own the function’s IAM role and its blast radius — an over-permissioned Lambda is a privesc target exactly like any other identity — the code, the dependencies, the data handling, and the configuration.
  • The trap: “serverless is secure” flattens into “I don’t have to think about security,” when what actually happened is the infrastructure security moved to the provider and the application and identity security stayed entirely with you — and those are where most serverless incidents live.

The function has no host for you to harden, which is genuinely less to worry about. Its identity and its code are unchanged in importance, and an over-scoped function role is the substrate-side version of the same finding this whole platform keeps producing.

Where you still run hosts — VMs, Kubernetes nodes, anything not fully managed — the fundamentals persist: minimize what’s installed, apply CIS benchmarks as a baseline, patch on a real cadence, and disable what you don’t use. Less mature than it sounds in practice, because drift erodes a hardened baseline the same way it erodes everything else — a host hardened at build time and never re-checked is hardened in the past tense.

The image is AppSec; the runtime is here, and admission control is where they meet. Kubernetes network policy is segmentation inside the cluster, pod escape and token abuse are what cloud pentesting targets, and runtime behaviour feeds detection. Every workload’s identity blast radius is an IAM question the platform can’t fix for you.

Graph View