Default Linux Capabilities for Containers in the Apple Container Runtime
The Apple Container runtime grants every container a restricted default set of 14 Linux capabilities—such as CAP_AUDIT_WRITE, CAP_CHOWN, and CAP_NET_BIND_SERVICE—while explicitly dropping all others to enforce least privilege.
Understanding the default Linux capabilities for containers is essential for securing workloads built with the Apple Container toolchain. The runtime initializes each container with a curated subset of kernel privileges that support common operational tasks without exposing unnecessary system interfaces. This article explains the exact default list, the design rationale behind it, and how to customize capabilities using the Apple Container CLI.
What Are the Default Linux Capabilities?
Containers launched by the Apple runtime receive only the capabilities documented in the “Control Linux capabilities” section of docs/how-to.md. Every capability outside this predefined list is dropped by default, preventing privileged operations that typical containerized applications do not require.
The Complete Default Capability List
According to the source documentation, the Apple Container runtime provides these 14 capabilities:
CAP_AUDIT_WRITE– Write audit recordsCAP_CHOWN– Change file ownershipCAP_DAC_OVERRIDE– Bypass file read, write, and execute permission checksCAP_FOWNER– Bypass permission checks on operations that normally require the filesystem UID to match the process UIDCAP_FSETID– Modify files without clearing set-user-ID and set-group-ID bitsCAP_KILL– Send signals to arbitrary processesCAP_MKNOD– Create special files usingmknodCAP_NET_BIND_SERVICE– Bind a socket to a privileged port below 1024CAP_NET_RAW– Use raw and packet socketsCAP_SETFCAP– Set arbitrary capabilities on a fileCAP_SETGID– Make arbitrary manipulations of process GIDsCAP_SETPCAP– Modify process capabilitiesCAP_SETUID– Make arbitrary manipulations of process UIDsCAP_SYS_CHROOT– Change the root directory withchroot
Why This Default Set Is Chosen
Apple selected these capabilities to cover the most common operational needs while minimizing attack surface:
- Audit and logging –
CAP_AUDIT_WRITElets the container write audit records for compliance and monitoring. - File and ownership operations –
CAP_CHOWN,CAP_FOWNER,CAP_FSETID, andCAP_DAC_OVERRIDEenable necessary file permission modifications. - Process management –
CAP_KILLsupports signal handling, whileCAP_SETUIDandCAP_SETGIDallow user and group ID changes inside the container. - Network functionality –
CAP_NET_BIND_SERVICEpermits binding to privileged ports, andCAP_NET_RAWsupports raw socket operations required by many networking tools. - Device and filesystem control –
CAP_MKNOD,CAP_SETFCAP,CAP_SETPCAP, andCAP_SYS_CHROOTprovide advanced filesystem and capability management.
How to Customize Default Linux Capabilities for Containers
Users can expand or shrink the default capability set using the --cap-add and --cap-drop flags on container run or container create. As implemented in Sources/Services/ContainerAPIService/Client/Flags.swift, the CLI accepts capability names with or without the CAP_ prefix and is case-insensitive.
Running with the Default Capability Set
No explicit flags are needed to use the defaults:
container run --rm alpine uname -a
This command launches the container with the 14 capabilities listed above.
Adding Capabilities with --cap-add
To grant a capability beyond the default set, use the --cap-add flag. For example, to add NET_ADMIN:
container run --cap-add NET_ADMIN --rm alpine ip link set lo down
The following syntax variations are all valid:
container run --cap-add NET_ADMIN alpine ip link set lo down
container run --cap-add CAP_NET_ADMIN alpine ip link set lo down
container run --cap-add net_admin alpine ip link set lo down
Dropping Capabilities with --cap-drop
To remove a capability from the default set, pass it to --cap-drop. Dropping CHOWN, for example, prevents file ownership changes:
container run --cap-drop CHOWN --rm alpine chown 100 /tmp
This command produces the expected permission error:
chown: /tmp: Operation not permitted
Granting or Removing All Capabilities
You can override the defaults entirely by using the ALL keyword. Adding ALL capabilities grants every available Linux capability:
container run --cap-add ALL --rm alpine sh -c "ip link set lo down && echo ok"
Conversely, dropping ALL capabilities and selectively adding back only what is needed restores a minimal privilege set tailored to the workload:
container run --cap-drop ALL --cap-add SETUID --cap-add SETGID --rm alpine id
The order of operations is critical: adds are applied after drops. Therefore, --cap-drop ALL --cap-add ALL ultimately grants every capability because the add operation supersedes the drop.
Where Defaults Are Defined in the Source Code
The default Linux capabilities for containers and the CLI override logic are documented and tested across three key locations in the repository:
docs/how-to.md– The “Control Linux capabilities” section documents the default list and provides CLI usage examples.Sources/Services/ContainerAPIService/Client/Flags.swift– Implements the parsing logic for--cap-addand--cap-drop, including case-insensitive matching and optionalCAP_prefix handling.Tests/IntegrationTests/Run/TestCLIRunCapabilities.swift– Contains integration tests that verify the runtime respects the default capability set and correctly applies flag overrides.
Summary
- The Apple Container runtime defaults to 14 Linux capabilities, dropping all others to reduce attack surface.
- Default capabilities cover audit logging, file ownership, process management, networking, and filesystem control.
- Use
--cap-addto grant additional capabilities and--cap-dropto remove defaults; the CLI is case-insensitive and accepts names with or without theCAP_prefix. - The
ALLkeyword overrides the entire set, and operations are applied with adds taking precedence over drops. - Definitions live in
docs/how-to.md, parsing logic inFlags.swift, and verification inTestCLIRunCapabilities.swift.
Frequently Asked Questions
What are the default Linux capabilities for containers in the Apple Container runtime?
Containers start with a restricted set of 14 capabilities: CAP_AUDIT_WRITE, CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_FOWNER, CAP_FSETID, CAP_KILL, CAP_MKNOD, CAP_NET_BIND_SERVICE, CAP_NET_RAW, CAP_SETFCAP, CAP_SETGID, CAP_SETPCAP, CAP_SETUID, and CAP_SYS_CHROOT. Every other capability is dropped by default to enforce least privilege according to the runtime documentation.
How do I add or drop Linux capabilities when running a container?
Use the --cap-add and --cap-drop flags with the container run or container create commands. The Apple Container CLI accepts capability names with or without the CAP_ prefix and ignores case, so NET_ADMIN, CAP_NET_ADMIN, and net_admin are interchangeable as implemented in the Flags parser.
What happens if I use --cap-drop ALL with the Apple Container CLI?
Dropping ALL removes every capability from the container. You can then selectively restore specific privileges with --cap-add. Because adds are processed after drops, a command like --cap-drop ALL --cap-add SETUID results in a container that retains only CAP_SETUID.
Does --cap-add ALL override the default Linux capability restrictions?
Yes. Passing --cap-add ALL grants the container every available Linux capability, completely replacing the restricted default set. Since adds are evaluated after drops, even --cap-drop ALL --cap-add ALL ends up granting full capabilities.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →