seccomp: filter syscalls
RuntimeDefault and curated Localhost profiles.
A container is just a process on the host, and the host kernel is one syscall away — a kernel bug reachable through an exotic syscall is a direct route out of the container. seccomp (secure computing mode) is the kernel feature that filters which syscalls a process may make, and it is the cheapest meaningful reduction of that surface. Container runtimes ship a sane default profile that blocks dozens of dangerous calls (mount, ptrace, kernel module loading), but Kubernetes runs pods seccomp-unconfined unless you explicitly ask for a profile.
The one-line, high-value win is RuntimeDefault: it turns the runtime’s curated filter back on for the pod, blocking the risky syscalls with near-zero chance of breaking a normal application. You can set it on a single pod, or enforce it fleet-wide, and it is exactly what the restricted Pod Security Standard requires.
apiVersion: v1kind: Podmetadata: { name: web, namespace: payments }spec:securityContext:seccompProfile:type: RuntimeDefault # the runtime’s curated allowlistcontainers:- name: appimage: registry.internal/web:1.4.2# a container-level seccompProfile here would override the pod default
A custom profile lives on the node
To go tighter than the default, you ship a JSON profile to every node under the kubelet’s seccomp directory and reference it with type: Localhost and a path relative to that directory. A profile has a default action (block everything, or log everything) and a list of explicitly allowed syscalls. The kubelet looks for it at /var/lib/kubelet/seccomp/, so localhostProfile: profiles/audit.json resolves to /var/lib/kubelet/seccomp/profiles/audit.json.
{"defaultAction": "SCMP_ACT_LOG", // log every syscall instead of blocking"architectures": ["SCMP_ARCH_X86_64"],"syscalls": []}// referenced from the pod:// seccompProfile: { type: Localhost, localhostProfile: profiles/audit.json }
How to build a real allowlist
You do not guess the syscalls an app needs — you observe them. Run it under an audit profile (defaultAction SCMP_ACT_LOG), exercise every code path, and read which syscalls it actually made from the audit log; then flip the default action to SCMP_ACT_ERRNO and list exactly those calls. That log-first workflow is the whole trick, and it is why the audit profile above is the starting point, not the destination.
# watch the syscalls the container makes under the audit profile$ sudo grep -i seccomp /var/log/syslog | tailaudit: type=1326 ... comm="app" syscall=41 ... # 41 = socket, keep itaudit: type=1326 ... comm="app" syscall=105 ... # 105 = setuid, investigate