seccomp Profile
A Linux kernel security feature that filters which system calls a container process is allowed to make. Docker applies a default seccomp profile blocking 44 dangerous syscalls — custom profiles can restrict further for high-security workloads.
seccomp Profile — Filtering System Calls in Docker Containers
What Is a seccomp Profile in Simple Terms?
Every action a program takes — reading a file, opening a network connection, creating a process — requires a system call (syscall) to the Linux kernel. seccomp (Secure Computing Mode) is a kernel feature that acts as a filter, blocking certain syscalls from being made.
Docker applies a default seccomp profile to every container that blocks 44 syscalls that are dangerous or unnecessary for most applications. Engineers rarely interact with seccomp directly, but understanding it helps explain why certain operations are blocked in containers.
Application code | | function call (e.g., socket()) vC library (glibc/musl) | | syscall instruction v+------------------------------------------+| seccomp filter || Is this syscall allowed? || YES -> pass to kernel || NO -> SIGKILL or EPERM |+------------------------------------------+ | vLinux kernelDocker's Default seccomp Profile
# Docker blocks these dangerous syscalls by default:# keyctl (cryptographic key management)# ptrace (process debugging/injection)# mount (mounting filesystems)# reboot (reboot the system)# kexec_load (load new kernel)# create_module (load kernel modules)# ... and 38 more # View the full default profilecurl https://raw.githubusercontent.com/moby/moby/master/profiles/seccomp/default.json # Most applications never need these syscalls# Blocking them prevents a compromised container from:# - Debugging other processes (ptrace)# - Loading kernel modules# - Mounting filesystems# - Rebooting the hostUsing seccomp in Docker
# Use default seccomp profile (automatic — already active)docker run -d payment-api:latest # Disable seccomp (NOT recommended — only for debugging)docker run -d --security-opt seccomp=unconfined payment-api:latest # Use a custom seccomp profiledocker run -d \ --security-opt seccomp=/etc/docker/custom-seccomp.json \ payment-api:latest # In Docker Composeservices: api: security_opt: * seccomp:/etc/docker/custom-seccomp.jsonWhen You Need Custom Profiles
Default profile blocks syscalls most apps never useSome legitimate apps need blocked syscalls: Strace/debugging tools: Need: ptrace syscall Solution: add ptrace to allowed list in custom profile Java applications: Some JVMs need: clone3 syscall Solution: add clone3 to allowed list High-security workloads: Want: block even more syscalls Solution: start with default profile, remove additional syscallsRememberseccomp profiles work alongside other security controls — they do not replace USER, cap_drop, or read-only filesystems. A fully hardened container uses all four: non-root user, dropped capabilities, read-only filesystem, and seccomp filtering. Each layer adds independent protection.
Frequently Asked Questions
What does Docker's default seccomp profile actually block, and why isn't it stricter by default?
The default profile blocks around 44 syscalls out of roughly 300+ available on Linux — things like `mount`, `reboot`, `ptrace`, and kernel module loading that a typical containerized application never legitimately needs but that could be used to escape or destabilize the host if a process were compromised. It isn't stricter by default because many syscalls are still legitimately needed by common runtimes and package managers, and a too-restrictive default would break a large fraction of ordinary images out of the box.
What's a common mistake when tightening seccomp profiles for a specific workload?
Writing a custom deny-list from scratch instead of generating an allow-list from actual observed syscall usage — tools like `strace` or Docker's own `--security-opt seccomp=trace.json` combined with runtime profiling (e.g. via Falco or `docker-slim`) capture exactly which syscalls a container uses in practice, avoiding the common outcome of a hand-written profile that breaks the app in a rarely-exercised code path (like a signal handler or crash-dump routine) that wasn't tested.