Linux Capabilities Explained: Process Privileges and Containers
Linux capabilities explain how a process can perform selected privileged operations without receiving every power traditionally associated with the root user. They matter to Linux administrators, developers, and platform engineers because container runtimes use them to reduce the privileges available to an application. This guide explains the capability sets, how they change across program execution, and how to inspect and limit them.
Why Linux Capabilities Matter
Containers share the host kernel, so a process that can change network settings, load kernel modules, or bypass file permissions can affect more than its own application data. A process does not always need all of those powers to do its job. Understanding Linux capabilities helps operators grant only the narrow privileges a workload needs instead of treating root access as a single on-or-off switch.
Capabilities are also a practical part of Linux security conversations because they sit between ordinary user and group permissions and broader controls such as namespaces, seccomp, and Linux Security Modules (LSMs). These controls address different parts of a process’s authority and are strongest when combined.
What Are Linux Capabilities?
Linux capabilities divide many operations historically associated with the superuser into distinct privileges. A capability such as CAP_NET_BIND_SERVICE permits binding to Internet ports below 1024, while CAP_NET_ADMIN permits selected network administration operations. The Linux capabilities manual page lists the capabilities and the operations they cover.
Capabilities are attributes of individual threads, not a single global property of a user account. A process running with user ID 0 can have capabilities removed, and a process with a nonzero user ID can receive a limited capability through mechanisms such as file capabilities. Ordinary ownership and permission checks still apply; a capability only affects kernel checks that recognize it.
The Linux kernel project implements these checks in the kernel. Its credentials documentation describes capabilities alongside user IDs, group IDs, and other information used when a task accesses a system object.
The Problem Capabilities Solve
Traditional Unix privilege models made root broadly powerful. That is convenient for system administration, but it gives a service more authority than it may need. If a network daemon only needs to bind a low-numbered port, granting it unrestricted root access also exposes unrelated administrative operations.
Capabilities make privilege grants more selective. A service can keep its normal identity and receive a specific capability, or a container runtime can remove capabilities from the process it starts. This reduces the consequences of a software flaw or configuration mistake, but it does not repair the flaw or replace other security boundaries.
How Linux Capabilities Work
The kernel tracks several capability sets for each thread. Their interaction is especially important when a program starts another executable with execve().
| Set | Meaning | Operational effect |
|---|---|---|
Permitted (P) |
Capabilities the thread may make effective | Acts as an upper limit on the thread’s active privileges |
Effective (E) |
Capabilities currently used for kernel permission checks | A capability generally needs to be effective when the relevant operation is attempted |
Inheritable (I) |
Capabilities eligible to cross an execution transition | Participates in calculating capabilities for the next executable |
Bounding (B) |
Ceiling on capabilities that can be acquired through file capabilities | Dropping a capability from this set is a lasting restriction for the thread and its descendants |
Ambient (A) |
Capabilities preserved across execution of non-privileged files | Supports launching ordinary programs with selected capabilities, subject to the other sets |
These are per-thread sets. Threads in one multi-threaded program can have different capability state, so a security design must account for how the application creates and configures its threads.
When a program executes another file, the kernel calculates the new thread’s sets using the current sets, the file’s permitted and inheritable capability metadata, and the file’s effective flag. This is why the word “inherit” can be misleading: a child does not automatically receive every capability of its parent. The exact result depends on the sets and on whether the executable carries file capabilities. The manual’s execve rules describe the complete calculation.
File capabilities are stored as metadata on an executable, so a program can receive a narrow privilege without being launched as root. They must be managed carefully: an executable with an unexpected file capability can expand the privileges of anyone who runs it. Inspect these attributes with getcap, and treat changes to them like changes to privileged access policy.
The kernel checks capabilities in a security context that also includes traditional credentials and other policies. A capability does not automatically grant access to every object: file permissions, namespaces, LSM policy, seccomp filters, and other restrictions can still deny an operation.
Common Capabilities and Related Controls
Some capabilities that frequently appear in server and container configurations include:
CAP_NET_BIND_SERVICE: permits binding to Internet ports below 1024, unless the host’s port policy makes that distinction unnecessary.CAP_NET_ADMIN: allows a range of network administration actions, such as changing routes or interface settings. It is broader than a process that only needs ordinary network access.CAP_NET_RAW: permits use of raw and packet sockets, which many applications do not need.CAP_SYS_ADMIN: covers a large collection of administrative operations. It is intentionally broad in practice and should not be treated as a small, routine permission.CAP_SYS_PTRACE: permits tracing or inspecting other processes in circumstances that would otherwise be restricted.
Capabilities are one layer in a larger isolation design. Linux namespaces change a process’s view of resources, while Linux seccomp filters system calls. LSMs such as AppArmor and application-focused restrictions such as Linux Landlock make other access decisions. The Linux container security guide discusses how these controls fit together.
The Open Container Initiative Runtime Specification gives container runtimes a standard way to configure Linux-specific controls, including process capabilities. Runtime configuration translates the administrator’s intent into the kernel state of the container’s process; the specification does not make every runtime or host configuration identical.
Real-World Uses
Container hardening: A container often needs fewer capabilities than the runtime initially makes available. Dropping unneeded capabilities narrows the privileged operations available to a compromised process. It is not equivalent to running the container without privileges: mounts, device access, user namespaces, and the host kernel still affect the boundary.
Small system services: A service may need one specific operation, such as binding a low port, but not broad root authority. A service manager or file capability can provide a narrower grant, although operators must check how the service’s user identity, executable, and launch configuration interact.
Debugging and observability: Tools that inspect processes, capture packets, or load certain BPF programs may require capabilities such as CAP_SYS_PTRACE, CAP_NET_RAW, or CAP_BPF. Granting these to an entire workload for convenience can expose more authority than the tool needs; use a dedicated, controlled diagnostic environment where possible.
User namespaces: A process can appear as UID 0 inside a user namespace while mapping to an unprivileged user outside it. Capabilities held in that namespace do not automatically confer the same authority over resources governed by the initial user namespace. They also do not override unrelated host permissions or restrictions.
Getting Started: Inspect and Limit Capabilities
On Debian or Ubuntu, install the libcap2-bin tools to inspect capabilities:
sudo apt update
sudo apt install libcap2-bin
Inspect the current shell’s capability sets using capsh and /proc:
capsh --print
grep '^Cap' /proc/self/status
effective=$(awk '/^CapEff:/ { print $2 }' /proc/self/status)
capsh --decode="$effective"
The hexadecimal fields in /proc/self/status represent bit sets; CapEff is the effective set. capsh --decode translates that mask into capability names. The output describes the process being inspected, not every thread or child process on the system. Use getpcaps PID to inspect a selected process and getcap /path/to/program to check file capabilities on an executable.
For a container test, compare the effective settings before and after dropping all capabilities:
docker run --rm alpine:3 sh -c 'grep "^Cap" /proc/self/status'
docker run --rm --cap-drop=ALL alpine:3 sh -c 'grep "^Cap" /proc/self/status'
Docker may need to download the image the first time. The second command requests that the runtime remove all capabilities from the container process; it does not remove other container controls or prove that the workload is otherwise isolated. If an application has a demonstrated need for one capability, add only that capability rather than restoring the full set:
docker run --rm \
--cap-drop=ALL \
--cap-add=NET_BIND_SERVICE \
alpine:3 sh -c 'grep "^Cap" /proc/self/status'
This example shows configuration, not a test of binding a privileged port. Confirm an application’s real behavior under the proposed policy in a non-production environment, and verify the actual process state after startup. User namespaces and daemon or host policy can further constrain which capabilities take effect. For Docker’s container options, consult the Docker run documentation.
Common Misconceptions
“A capability replaces normal file permissions.” It does not. A capability can affect a particular kernel permission check, but ordinary user and group permissions, ACLs, mount settings, and LSM policy can still deny access.
“Root always has every capability.” Root’s effective privileges depend on the thread’s capability sets, execution history, user namespace, and other security controls. UID 0 is important, but it is not a universal bypass of every kernel policy.
“Dropping capabilities makes a container secure.” Capability reduction is useful but incomplete. A container still depends on namespaces, seccomp, LSM policy, device and mount configuration, resource controls, and the security of the shared host kernel. Use defense in depth and grant exceptions only when a workload requires them.
“All capabilities are equally narrow.” Some capabilities cover a focused operation; others, particularly CAP_SYS_ADMIN, include many operations. Review the documented effects of each grant rather than judging by the capability’s name.
Related Articles
- Linux namespaces and container isolation
- Linux seccomp and system-call sandboxing
- Linux Landlock sandboxing
- Linux container security
- AppArmor security hardening
Changelog and Last Updated
- Initial publication; technical details reviewed against current kernel and runtime documentation.

