seccomp syscall filtering
RuntimeDefault and custom default-deny profiles.
The first hardening control to reach for is seccomp — it shrinks the kernel attack surface a container can touch, which is exactly where escapes and post-exploitation live. A container that cannot call mount, ptrace, or keyctl has lost the tools for many escape techniques.
Syscall filtering with seccomp-BPF
seccomp (secure computing mode) filters which syscalls a process may make, using a BPF program that allows, denies, or errors on each call. A container typically needs only a few dozen of the ~350 syscalls; blocking the rest removes capabilities an attacker relies on without affecting the workload. Kubernetes and container runtimes ship a curated RuntimeDefault profile that blocks the dangerous syscalls while allowing normal workloads — and yet many clusters still run Unconfined, leaving the full syscall surface open.
# Kubernetes: opt every pod into the curated default (do this by policy).apiVersion: v1kind: Podspec:securityContext:seccompProfile:type: RuntimeDefault # blocks ~44 dangerous syscalls; safe for most# A tighter custom profile (Localhost) for a known workload: default-deny,# allow only the syscalls the app actually uses.{ "defaultAction": "SCMP_ACT_ERRNO","syscalls": [{ "names": ["read","write","openat","connect","futex"],"action": "SCMP_ACT_ALLOW" }] }
Building a profile that fits
RuntimeDefault is the right baseline for most workloads; for high-value services you can go tighter with a default-deny profile that allows only the syscalls the app makes, generated by recording a workload under a tracer or with the Security Profiles Operator. The tradeoff is maintenance — too tight and a code path breaks; too loose and you gain little. Start at RuntimeDefault everywhere (enforced by policy), then invest in bespoke profiles for the workloads that warrant it.