Linux Seccomp: System-Call Sandboxing Explained
Linux seccomp is a kernel feature that lets a process restrict which system calls it can make. It matters to developers, platform engineers, and Linux administrators because containers share the host kernel: reducing unnecessary calls can narrow the interface available to a compromised application. This guide explains how filters work, how container runtimes apply them, and where syscall filtering fits among other isolation controls.
Why Linux Seccomp Is Being Discussed
Containers package applications consistently, but they do not normally provide each application with a separate kernel. Every process still requests services from the host kernel through system calls such as opening files, creating processes, and mapping memory. A smaller set of available calls can reduce the kernel functionality a workload can exercise if the application is misused or compromised.
That makes seccomp important in container hardening, Kubernetes policy, and sandboxed execution. It is also easy to overstate: seccomp filters system-call requests, not the whole behavior of a program. Understanding what the filter can inspect—and what it cannot—helps teams use it as one layer rather than treating it as a complete security boundary.
What Is Linux Seccomp?
Secure computing mode, usually shortened to seccomp, is a Linux kernel facility for restricting a process’s system calls. A filter evaluates information about a requested call, such as its number and arguments, then returns an action: allow it, deny it, log it, or take another supported response. The Linux kernel’s seccomp filter documentation describes the filter mechanism as a Berkeley Packet Filter (BPF) program.
The kernel has a strict mode with a very small permitted call set, but the mode used for container policies is seccomp filter mode. A process or runtime installs one or more filters before application code runs. Once attached, a filter cannot be removed by the process. Child processes inherit the filter when they are created, and it remains in effect across an allowed program execution transition.
Seccomp is not a separate container technology. It can be used by an individual application, a container runtime, or a higher-level platform. For a container, Docker or another runtime typically installs a profile while setting up the process, so the application starts with the policy already active.
The Problem Seccomp Solves
Linux exposes a broad system-call interface because different applications need different kernel services. A web server, image converter, database, and build tool will not use exactly the same calls. Many processes do not need privileged operations such as loading kernel modules, changing system time, or mounting filesystems, yet those calls are part of the kernel interface.
A seccomp policy can make unneeded operations unavailable to a workload. This does not fix a vulnerable application or prevent every attack, but it can reduce the number of kernel entry points reachable from that process. The Docker seccomp documentation explains Docker’s default profile and why a carefully chosen default offers protection while preserving broad application compatibility.
The boundary is deliberately narrow. Seccomp is not a filesystem permission system, a network firewall, or a resource quota. It cannot safely inspect the contents of arbitrary pointers passed as system-call arguments, so it is not suitable for rules such as “allow opening this path but deny that path.” Filesystem and network isolation need other mechanisms, including namespaces, capabilities, Linux security modules, and runtime configuration.
How Seccomp Works
At the kernel interface, a process installs a filter through the seccomp() system call or the related prctl() interface. A filter evaluates metadata about each system-call request, including the architecture, call number, and argument values. It cannot dereference pointers supplied by the process. This limitation keeps evaluation bounded and avoids a class of race conditions that can affect systems that inspect mutable application memory.
Filters return actions with defined precedence. A policy can allow a call, return an error to the application, log the attempt, signal the process, terminate a thread or process, or ask a configured userspace supervisor to handle a notification. The kernel chooses the most restrictive applicable action when multiple filters are attached. A process may add further filters to narrow its access, but cannot use a later filter to loosen an earlier restriction.
| Action | Typical effect | Practical consideration |
|---|---|---|
ALLOW |
The requested system call proceeds | Use only for calls the workload needs |
ERRNO |
The call is denied and an error is returned | Applications may report EPERM, EACCES, or another configured error |
TRAP |
The process receives SIGSYS |
Useful for controlled handling, but requires application support |
KILL_PROCESS |
The process is terminated | A strict response can turn one unexpected call into an outage |
LOG |
The call proceeds and can be recorded | Logging depends on kernel and system logging configuration; it is not a denial |
USER_NOTIF |
A userspace supervisor receives a notification | Adds a privileged, stateful component that must be designed carefully |
When a filter is attached to a thread, that thread is constrained. New processes inherit filters, but multithreaded programs need care because threads can have distinct filter state unless the installer synchronizes them. Container runtimes normally arrange the policy during process creation so application threads start inside the intended boundary.
Container profiles express policy in a runtime-specific configuration format rather than asking operators to hand-author raw BPF. A profile can define a default action and then allow a set of calls, sometimes with argument-specific conditions. Docker applies its default seccomp profile to containers unless it is overridden; that profile is designed to balance a smaller syscall surface with compatibility. A custom profile is a replacement policy, not necessarily a small patch merged into the default, so it must account for the full workload.
Components and Security Boundaries
Several separate concepts are often grouped under “container security”:
- Kernel filter: Evaluates system-call requests from a process and applies the configured action.
- Runtime profile: Translates a higher-level policy into the filter installed for the container. Docker’s default profile is one example; other runtimes maintain their own defaults.
- Namespace isolation: Gives processes separate views of resources such as process IDs, mounts, and networks. See the guide to Linux namespaces and container isolation.
- Capabilities and Linux security modules: Limit privileged operations and apply additional access-control rules. See Linux capabilities and process privileges for how capability sets restrict privileged operations, and Linux Landlock sandboxing for an application-focused filesystem restriction model.
- Platform policy: Kubernetes can request a runtime’s default profile through
seccompProfile: RuntimeDefault, while Pod Security Admission can check whether Pod security settings meet selected standards. The Kubernetes Pod Security Admission guide explains the admission layer.
These controls solve different problems. A seccomp rule can deny a system-call operation, but it does not decide whether a path is readable, isolate a network interface, or cap memory use. The Open Container Initiative Linux runtime configuration describes the broader Linux-specific settings that container runtimes coordinate. For workloads that need a different kernel boundary, gVisor uses a userspace application kernel rather than relying only on a host-kernel syscall filter.
Real-World Use Cases
General-purpose containers: A runtime default profile blocks selected calls that ordinary application containers rarely need, while allowing common programs to work. This is a practical baseline for container deployments that do not require specialized kernel operations.
Kubernetes workloads: A Pod can request RuntimeDefault so the node’s runtime applies its default seccomp policy. Teams can combine this with non-root execution, dropped capabilities, and a restrictive Pod Security Admission level. The effective profile remains runtime-dependent, so a cluster’s node configuration matters.
Dedicated appliances and services: An application with a stable workload can use a narrower profile after its startup, health checks, and normal operating paths have been tested. Compatibility testing is especially important for software that loads plugins, uses unusual networking or storage features, or invokes helper programs.
Untrusted or multi-tenant code: Seccomp can reduce direct access to selected kernel calls, but it should not be the only boundary. Teams handling customer code or generated programs may evaluate stronger runtime designs such as gVisor’s sandboxed container runtime, alongside resource limits, credential isolation, and network restrictions.
Getting Started: Apply and Verify a Runtime Default
Seccomp is built into supported Linux kernels; there is no separate package to install for a container user. On a Linux host, the kernel configuration can be checked when its build configuration is available:
grep -E '^CONFIG_SECCOMP(=|_)' "/boot/config-$(uname -r)"
Docker enables its default seccomp profile for ordinary containers unless the runtime configuration overrides it. Check the daemon’s reported security options and confirm that a test process is running in filter mode:
docker info --format '{{json .SecurityOptions}}'
docker run --rm alpine:latest sh -c 'grep "^Seccomp:" /proc/self/status'
On Linux, Seccomp: 2 in /proc/self/status indicates filter mode is active. It does not reveal the full policy or prove that every other container control is configured correctly. Docker Desktop runs Linux containers inside its Linux environment, so host details can differ from a native Linux installation.
For Kubernetes, set a Pod-level profile to the runtime’s default rather than assuming a specific profile is identical across different nodes:
apiVersion: v1
kind: Pod
metadata:
name: seccomp-check
spec:
securityContext:
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: nginx:alpine
Save this as seccomp-check.yaml, then apply and inspect the running process:
kubectl apply -f seccomp-check.yaml
kubectl exec seccomp-check -- grep '^Seccomp:' /proc/1/status
kubectl delete pod seccomp-check
Confirm the policy on the actual node runtime and test the application’s full workflow before enforcing a custom profile. If an application fails after hardening, identify the denied operation from its error, runtime diagnostics, and controlled testing. A failed operation may indicate a legitimate dependency, but do not add a syscall to a profile until its purpose and risk are understood. Prefer keeping the runtime default when a custom policy cannot be validated and maintained.
Common Misconceptions
“Seccomp is a complete sandbox.” The kernel documentation explicitly treats syscall filtering as one mechanism for reducing the exposed kernel surface, not a complete sandbox. Combine it with namespaces, capabilities, filesystem controls, resource limits, and a suitable runtime boundary.
“A process can use seccomp to block access to a specific file.” A filter cannot safely inspect the data behind a pointer argument. Use filesystem permissions, mounts, or a Linux security module for path-based decisions.
“A stricter profile is always safer.” A profile that blocks required calls can break startup, updates, or health checks. Teams may respond by granting broad privileges or disabling controls, which can undermine the intended protection. Measure a workload, document exceptions, and keep the policy under review.
“Every runtime’s default profile is the same.” The runtime and its version determine the effective default. Kubernetes RuntimeDefault delegates this choice to the node’s container runtime; it does not define one universal syscall list.
Related Articles
- Linux namespaces and container isolation
- Linux container security: isolation and hardening
- Container security best practices
- Kubernetes Pod Security Admission
- gVisor sandboxed container runtime
Changelog
- Initial publication.
Last updated: October 28.

