Skip to main content

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.

◈ DIAGRAM
Application code
|
| function call (e.g., socket())
v
C library (glibc/musl)
|
| syscall instruction
v
+------------------------------------------+
| seccomp filter |
| Is this syscall allowed? |
| YES -> pass to kernel |
| NO -> SIGKILL or EPERM |
+------------------------------------------+
|
v
Linux kernel

Docker's Default seccomp Profile

Bash
# 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 profile
curl 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 host

Using seccomp in Docker

Bash
# 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 profile
docker run -d \
--security-opt seccomp=/etc/docker/custom-seccomp.json \
payment-api:latest
# In Docker Compose
services:
api:
security_opt:
* seccomp:/etc/docker/custom-seccomp.json

When You Need Custom Profiles

TEXT
Default profile blocks syscalls most apps never use
Some 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 syscalls
Remember

seccomp 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.