Docker Seccomp Profiles, Explained From Zero

Docker Seccomp Profiles, Explained From Zero

How Docker quietly locks the door on thousands of Linux kernel abilities a container will probably never need — and why that one setting stops entire categories of attacks cold.

Picture a new employee’s office key card. It doesn’t open every door in the building — it opens the front entrance, their own floor, and the break room, and nothing else. Even if that employee’s laptop is stolen and someone tries to badge into the server room with it, the card simply doesn’t work there. That’s the entire idea behind a seccomp profile. A running container talks to the Linux kernel constantly, through hundreds of low-level requests called “system calls,” but almost none of those containers need access to the full, enormous set of things the kernel is capable of doing. Seccomp is the mechanism that hands each container a key card programmed to open only the doors it actually needs — and locks every other door, even if something inside the container is compromised and tries to reach for them.

1What Is Seccomp, and Why Does Docker Use It?

Understanding seccomp starts with understanding what a system call actually is.

Every program is constantly asking the kernel for favors

An application never directly touches hardware, memory outside its own space, the network card, or the filesystem. Instead, it asks the operating system’s kernel to do these things on its behalf, through a request called a system call (often shortened to “syscall”). Opening a file, sending a network packet, creating a new process, changing file permissions, and even asking what time it is — all of these are system calls. A typical Linux system exposes several hundred of them.

Where “seccomp” comes from

Seccomp stands for “secure computing mode,” a Linux kernel feature that lets a process restrict which system calls it — and anything it spawns — is allowed to make. Once a strict seccomp filter is applied to a process, any attempt to make a system call outside its allowed list is intercepted by the kernel itself before the call ever actually executes, and the kernel can choose what happens next: block it, kill the process, or simply pretend the call doesn’t exist.

Simple Analogy

Imagine a hotel room’s phone that can only dial the front desk and room service — the wiring physically doesn’t support dialing anywhere else. Even if someone inside wanted to make an international call, the phone itself is incapable of it. Seccomp does the same thing to a process’s ability to talk to the kernel.

Why containers specifically need this

A container is not a fully separate machine — it’s a set of regular Linux processes given the illusion of isolation through namespaces and control groups, while still sharing the exact same kernel as the host and every other container on that host. If a container is compromised, the attacker’s code is running as a Linux process capable, in principle, of making any system call the kernel supports — including ones that could destabilize the kernel, escape container isolation, or attack the host directly. Docker addresses this by applying a seccomp filter to every container by default, dramatically shrinking the set of system calls available to it, long before an attacker ever gets the chance to try one.

Syscall

Kernel request

A low-level request from a running program asking the Linux kernel to do something on its behalf.

Seccomp

Kernel filter feature

A Linux capability that lets a process’s allowed system calls be restricted and enforced by the kernel itself.

Profile

The rule set

A named, structured description of exactly which system calls are allowed, blocked, or specially handled for a container.

Attack Surface

What’s exposed

The full set of kernel functionality reachable from inside a container — seccomp exists specifically to shrink this.

i
Good to Know

Seccomp is not unique to Docker or even to containers generally. Browsers, sandboxed apps, and many security-conscious Linux services also use seccomp to restrict themselves. Docker simply applies the same kernel feature automatically, on every container, without requiring the application inside to opt in.

2The Building Blocks of Docker’s Seccomp Architecture

Several layers cooperate to turn a JSON file into real kernel-level enforcement.

1. The Linux Kernel’s Seccomp Subsystem

The actual enforcement engine, built directly into the kernel. It evaluates every system call a process attempts against a set of rules and decides in real time whether to allow it, block it, or take some other action.

2. BPF (Berkeley Packet Filter) Rules

Modern seccomp filters are compiled into small, efficient BPF programs — the same underlying technology originally built for filtering network packets — which the kernel can evaluate extremely quickly on every single system call without meaningfully slowing the process down.

3. The Seccomp Profile (JSON Definition)

A structured, human-editable file describing which system calls are allowed or blocked, and under what conditions. Docker translates this file into the low-level BPF rules the kernel actually understands.

4. The Container Runtime (runc)

The low-level component that actually starts a container’s processes. It is responsible for applying the compiled seccomp filter to the container’s very first process, before that process executes a single instruction of the application inside it.

Where the profile lives, structurally

A seccomp profile is, at its core, a list of system call names grouped by the action to take against them, plus a default action for any system call not explicitly listed. Docker ships with a built-in default profile covering the vast majority of everyday container needs, and also supports loading a completely custom profile from a file when finer control is required.

flowchart TB
    A["docker run
--security-opt seccomp=profile.json"] --> B["Docker Engine"] B --> C["Parse & Validate
Seccomp Profile JSON"] C --> D["Container Runtime (runc)"] D --> E["Compile Profile into
BPF Filter Program"] E --> F["Attach Filter to Container's
First Process (PID 1)"] F --> G["Kernel Seccomp Subsystem
enforces on every syscall"]
FIG 1 — From a JSON profile to a live kernel-enforced filter
!
Common Misconception

Seccomp filtering is not applied by Docker’s daemon watching over the container from the outside. It’s compiled directly into the container’s own process at startup and enforced by the kernel itself — Docker’s daemon isn’t even involved once the container is running.

3How a Single System Call Actually Gets Filtered

The enforcement happens on every syscall, one at a time, at kernel speed.

Once a filter is attached to a process, every single system call that process (or anything it spawns) makes is intercepted at the exact moment it’s invoked — before the kernel does any of the actual work the call requested. The kernel checks the call’s number, and often its specific arguments, against the compiled rule set, and only then decides what happens next.

1

Process Requests a Syscall

Code running inside the container — the application itself, or a library it depends on — triggers a system call, such as opening a file or creating a socket.

2

Kernel Intercepts Before Execution

Before the kernel performs the requested action, the attached seccomp BPF filter is evaluated against the syscall number and its arguments.

3

Filter Returns a Verdict

The filter evaluates to one specific action for this call — commonly allow, deny-with-error, or terminate — based on the profile’s rules.

4

Kernel Carries Out the Verdict

If allowed, the kernel proceeds exactly as it would without seccomp involved at all. If blocked, the kernel takes the configured action instead of performing the real work.

Critically, this evaluation happens for every syscall, every time, for the entire life of the process — it’s not a one-time check at container start. A process that behaves normally for an hour and then, because of a vulnerability being exploited, suddenly attempts a forbidden syscall will be blocked on that specific attempt, just as reliably as it would have been blocked in the very first second.

“Seccomp doesn’t ask whether a process looks trustworthy — it simply refuses to perform anything not on the list, no matter how the request arrived.”

4The Actions a Seccomp Rule Can Take

“Blocked” isn’t one single behavior — seccomp supports several distinct responses.

A seccomp profile doesn’t just say yes or no. Each rule specifies one of several possible actions, and different actions produce very different experiences for the application running inside the container.

Allow

SCMP_ACT_ALLOW

The system call proceeds completely normally, exactly as if no seccomp filter existed at all.

Errno

SCMP_ACT_ERRNO

The call is blocked, and the calling process receives a normal-looking “permission denied” style error, as if the operation simply failed. Most applications handle this gracefully.

Kill

SCMP_ACT_KILL

The offending process (or the entire thread group, depending on the exact variant) is terminated immediately the moment it attempts the call.

Trap

SCMP_ACT_TRAP

The kernel sends a signal to the process instead of silently failing or killing it, allowing custom handling if the application is written to expect it.

Log

SCMP_ACT_LOG

The call is allowed to proceed, but the kernel records that it happened — useful for observing real-world syscall usage before tightening a profile.

Trace

SCMP_ACT_TRACE

Hands the decision off to an external tracing process, giving fine-grained, programmable control — rarely used in typical container deployments.

i
Practical Tip

Errno-based blocking is generally friendlier for real-world applications than kill-based blocking, because many programs already expect certain operations to fail occasionally and simply move on, while an unexpected kill can look like a mysterious crash with no clear explanation.

5Docker’s Default Profile vs Writing a Custom One

Most containers never need a custom profile — but knowing when they do matters.

The default profile

Docker ships with a built-in default seccomp profile that is automatically applied to every container unless something else is explicitly configured. This default profile blocks a substantial list of system calls that are rarely needed by typical applications and have a history of being used in container-escape or kernel-exploitation techniques, while allowing everything a normal web server, database, or general-purpose application is likely to need.

Why a custom profile is sometimes necessary

Some workloads legitimately need a system call the default profile blocks — certain low-level networking tools, specialized monitoring agents, or software that manages other processes in unusual ways. In these cases, teams can supply their own profile file, either loosening the default just enough to permit the specific calls needed, or building a profile from scratch tailored precisely to what the application actually uses.

Using the Default Profile

  • Works out of the box for the overwhelming majority of applications
  • Maintained and updated by the Docker project as new risks are identified
  • No extra effort required from application teams

Building a Custom Profile

  • Requires understanding exactly which syscalls the application genuinely uses
  • Can be tightened far beyond the default for especially sensitive workloads
  • Needs ongoing maintenance as the application’s dependencies change

Disabling seccomp entirely

Docker also allows seccomp filtering to be turned off entirely for a specific container, most commonly used for legacy applications that need broad, unrestricted kernel access or during troubleshooting to determine whether seccomp is the cause of an unexpected failure. This should be treated as a deliberate, reviewed exception rather than a routine setting.

Simple Analogy

The default profile is like the standard key card every new employee gets on day one — good enough for almost everyone. A custom profile is like requesting a card reprogrammed for the specific extra doors your job actually requires, rather than just handing out a master key because asking for the right doors takes more effort.

6How Seccomp Fits Alongside Docker’s Other Defenses

Seccomp is one layer in a deliberately layered defense, not the whole story.

Seccomp doesn’t work alone. Docker containers are also constrained by Linux capabilities (which restrict specific privileged operations rather than entire syscalls), AppArmor or SELinux mandatory access control profiles (which restrict file and resource access by path and label), and user namespaces (which can remap a container’s root user to an unprivileged user on the host). Each of these mechanisms restricts a different dimension of what a container can do, and together they form overlapping layers of defense.

Seccomp
RESTRICTS WHICH SYSCALLS
Capabilities
RESTRICTS PRIVILEGED ACTIONS
AppArmor/SELinux
RESTRICTS FILE & RESOURCE ACCESS

This layering matters because no single mechanism is a complete solution on its own. A syscall that seccomp allows might still be blocked by a capability restriction, and a file access that passes capability checks might still be denied by AppArmor. An attacker has to get past every applicable layer, not just one, to achieve something the container was never meant to allow.

i
Good to Know

These mechanisms are evaluated independently, and any one of them denying an action is enough to block it. Loosening a seccomp profile does not automatically grant capabilities or file access that another layer still restricts.

7Advantages, Disadvantages, and Trade-offs

Seccomp meaningfully raises the bar for attackers, but it isn’t free of friction.

Advantages

  • Blocks entire categories of kernel-level exploits before the vulnerable code path is ever reachable
  • Enforced by the kernel itself, with essentially no way for a compromised process to disable it from the inside
  • Extremely low performance overhead thanks to efficient BPF-based evaluation
  • Enabled automatically by default, requiring zero effort for the common case
  • Fine-grained enough to allow exactly the syscalls a workload needs and nothing more

Disadvantages / Trade-offs

  • An overly strict custom profile can break an application in confusing, hard-to-diagnose ways
  • Determining exactly which syscalls a complex application genuinely needs can take real effort
  • Kill-based enforcement can produce abrupt, unexplained crashes rather than graceful errors
  • Profiles need maintenance as application dependencies and their syscall usage evolve over time
  • It only restricts kernel-level requests — it does nothing to stop application-level logic flaws

8Security Considerations

Seccomp is a powerful tool, but it’s easy to accidentally weaken it without noticing.

The temptation to loosen, and its cost

When an application fails mysteriously, disabling seccomp entirely is often the fastest way to make the error disappear — which makes it a tempting, dangerous shortcut. Removing the protection instead of identifying the specific blocked syscall trades a diagnosable, fixable problem for a much larger, permanent increase in attack surface, often without anyone circling back to re-enable it later.

Privileged containers bypass seccomp’s value

Running a container in fully privileged mode grants it capabilities and access that make seccomp’s syscall restrictions far less meaningful in practice, since so much else is already permitted. Teams sometimes reach for privileged mode to solve a permission problem that a much narrower, targeted change — like a custom seccomp profile or a specific added capability — would have solved with far less exposure.

Audit

Review custom profiles

Any custom or loosened profile should go through the same review process as other security-relevant configuration changes.

Least Privilege

Start narrow, expand carefully

Prefer adding specific allowed syscalls to a strict baseline over starting from an open profile and trying to remove risky ones.

Kernel Currency

Keep the host kernel updated

Seccomp’s protection is only as good as the kernel enforcing it — an outdated kernel may carry vulnerabilities seccomp alone cannot mitigate.

Defense in Depth

Don’t rely on seccomp alone

Combine it with capability restrictions, mandatory access control, and non-root users rather than treating it as a complete solution by itself.

!
Common Mistake

Disabling seccomp as a permanent fix rather than a temporary diagnostic step. Once the specific blocked syscall is identified, the far safer fix is almost always a narrowly customized profile, not the complete removal of the protection.

9Monitoring, Logging, and Metrics

Because kernel-level blocking is silent by design, visibility has to be built in deliberately.

What a blocked syscall looks like from the outside

When a system call is denied with an error, the application inside the container simply sees a failed operation — nothing about the failure inherently says “this was seccomp.” When a process is killed, it looks, from the outside, like a crash. Without dedicated visibility into seccomp specifically, these events easily get misdiagnosed as application bugs.

Kernel audit logging

Linux’s audit subsystem can be configured to record seccomp denials, giving a system-wide log of exactly which syscall was blocked, by which process, and when — a critical resource for both debugging and detecting real attack attempts.

The Log action for tuning

Setting a profile’s default or specific rules to the log action, rather than outright blocking, lets teams observe exactly which syscalls a workload actually attempts in a realistic environment before committing to a stricter profile.

Runtime security tooling

Dedicated container runtime security tools can watch syscall activity in real time, alerting on unusual patterns — such as a web application suddenly attempting syscalls associated with process injection or privilege escalation — independent of what the seccomp profile itself allows or blocks.

“A blocked syscall that nobody logs is a security control operating completely in the dark — effective, but invisible until something goes wrong.”

10Design Patterns and Anti-Patterns

The gap between using seccomp well and using it carelessly is mostly about discipline.

Pattern: profile per application family

A mature pattern is maintaining a small number of purpose-built profiles — one for general web services, one for database workloads, one for specialized system-level tools — rather than either a single one-size-fits-all profile for everything or a unique bespoke profile per individual container, which becomes unmanageable at scale.

Pattern: log-then-restrict rollout

Rolling out a tightened profile in log-only mode first, observing real production syscall activity for a representative period, and only then switching the same rules to actual enforcement, catches legitimate-but-unanticipated syscall usage before it causes an outage.

ANTI-PATTERN-01 Avoid
Problem

Disabling seccomp entirely across an environment because one application, at some point, hit a blocked syscall.

Why It’s Harmful

This removes a kernel-enforced protection for every container in the environment to solve what was really a single application’s narrow, specific need.

Correct Approach

Identify the exact blocked syscall for that one workload and apply a narrowly scoped custom profile only to the containers that genuinely require it.

ANTI-PATTERN-02 Avoid
Problem

Copying an extremely permissive “allow everything” custom profile from an online example without adapting it, just to make an error go away quickly.

Why It’s Harmful

This silently reintroduces most of the risk seccomp exists to mitigate, while giving a false sense of security because a profile file is technically still “in use.”

Correct Approach

Start from Docker’s default profile and add only the specific syscalls a documented investigation shows are actually required.

11Best Practices and Common Mistakes

Small operational habits separate teams that use seccomp effectively from teams that fight it constantly.

Practice

Start from the default profile

Treat Docker’s built-in default as the baseline for every workload, and only diverge from it with a clear, documented reason.

Practice

Version-control custom profiles

Store custom profile files in source control alongside the application, reviewed the same way application code changes are reviewed.

Practice

Test profile changes in staging first

Validate any custom or tightened profile against realistic workloads before it reaches production, since some syscall usage only appears under specific conditions.

Practice

Prefer errno over kill where practical

Choose an error-returning action over process termination for non-critical restricted calls, so applications degrade gracefully instead of crashing outright.

Mistake

Disabling seccomp as a first troubleshooting step

Jumping straight to turning seccomp off, instead of first identifying which specific syscall is being blocked and why.

Mistake

Never revisiting old custom profiles

Leaving a custom profile untouched for years while the underlying application and its dependencies change, until it no longer reflects real usage.

12Real-World and Industry Examples

Seccomp isn’t a theoretical control — it’s one of the most widely relied-upon container security defaults in production today.

Cloud-managed container platforms

Major managed container and Kubernetes platforms apply seccomp filtering by default to workloads running on their infrastructure, treating it as a baseline security control rather than an optional add-on customers must configure themselves.

Container image and runtime security scanners

Security scanning tools that assess container configurations commonly flag disabled or overly permissive seccomp settings as a finding, alongside checks like running as root or using privileged mode, reflecting how central seccomp has become to baseline hardening expectations.

Regulated industries and compliance frameworks

Organizations in finance, healthcare, and other regulated sectors frequently include seccomp enforcement as part of internal container hardening standards, since it provides a concrete, auditable control that maps well onto broader “least privilege” compliance requirements.

Vulnerability research and CVE history

Several real-world Linux kernel vulnerabilities that could otherwise have been triggered from inside a container have historically relied on syscalls that Docker’s default seccomp profile already blocks, meaning containers running with the default profile were protected even before a patch was available.

13Frequently Asked Questions

Q1Is seccomp enabled by default when I run a container?

Yes. Docker applies its built-in default seccomp profile automatically to every container unless it’s explicitly overridden or turned off.

Q2Does seccomp protect against every kind of container attack?

No. It restricts which kernel system calls are reachable, which blocks a specific and significant category of kernel-level attacks, but it does nothing about application-level vulnerabilities like injection flaws or business-logic issues.

Q3Will a stricter seccomp profile slow my container down?

The performance overhead of seccomp filtering itself is very small, since it’s implemented with efficient kernel-level BPF evaluation. Any slowdown users notice is far more commonly caused by a blocked syscall making an operation fail and retry, not by the filtering mechanism itself.

Q4Can an application inside the container detect or change its own seccomp filter?

A process cannot loosen a seccomp filter already applied to it — seccomp filters can only ever be made more restrictive, never relaxed, once attached, which is a deliberate part of the kernel design.

Q5Is seccomp the same thing as AppArmor or SELinux?

No. Seccomp restricts which system calls are reachable at all. AppArmor and SELinux instead restrict what specific files, paths, and resources an allowed action can touch. Docker commonly applies both kinds of controls together.

Q6How do I figure out which syscalls my application actually needs before writing a custom profile?

The safest approach is running the workload with a profile set to log unfamiliar syscalls rather than block them, observing real activity under realistic conditions, and building the allow list from that observed behavior rather than guessing.

14Summary and Key Takeaways

Seccomp profiles are one of the most impactful, least visible security controls Docker applies by default. By restricting which of the Linux kernel’s hundreds of system calls a container is even permitted to attempt, seccomp closes off an entire category of kernel-level exploitation before it becomes relevant — enforced directly by the kernel itself, with essentially no performance cost and no requirement for the application inside to be seccomp-aware at all. Understanding how profiles are structured, what actions a blocked call can trigger, and how seccomp fits alongside capabilities and mandatory access control turns it from an invisible background setting into a deliberate, tunable part of a container’s security posture.

Key Takeaways

  • Seccomp restricts system calls, not application logic. It controls which requests a process can make to the kernel, not what the application does within those allowed requests.
  • Enforcement happens in the kernel via BPF. Once attached, the filter is evaluated on every syscall with minimal overhead, and cannot be loosened from inside the process.
  • Blocked calls can behave differently. Errno returns a graceful failure; kill terminates the process outright — the choice of action meaningfully affects application behavior.
  • Docker’s default profile covers most workloads. Custom profiles are for genuine exceptions, not a routine first response to an error.
  • Disabling seccomp should be a deliberate, reviewed exception — never a default troubleshooting shortcut.
  • It’s one layer among several. Seccomp works alongside Linux capabilities and mandatory access control systems like AppArmor or SELinux, not in place of them.
  • Visibility must be built in deliberately. Kernel audit logging and the log action are what turn silent enforcement into something teams can actually observe and tune.