# Default Linux Capabilities for Containers in the Apple Container Runtime

> Discover default Linux capabilities for containers in Apple's runtime. Learn how 14 essential capabilities enforce least privilege while others are dropped.

- Repository: [Apple/container](https://github.com/apple/container)
- Tags: internals
- Published: 2026-07-05

---

**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`](https://github.com/apple/container/blob/main/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 records
- **`CAP_CHOWN`** – Change file ownership
- **`CAP_DAC_OVERRIDE`** – Bypass file read, write, and execute permission checks
- **`CAP_FOWNER`** – Bypass permission checks on operations that normally require the filesystem UID to match the process UID
- **`CAP_FSETID`** – Modify files without clearing set-user-ID and set-group-ID bits
- **`CAP_KILL`** – Send signals to arbitrary processes
- **`CAP_MKNOD`** – Create special files using `mknod`
- **`CAP_NET_BIND_SERVICE`** – Bind a socket to a privileged port below 1024
- **`CAP_NET_RAW`** – Use raw and packet sockets
- **`CAP_SETFCAP`** – Set arbitrary capabilities on a file
- **`CAP_SETGID`** – Make arbitrary manipulations of process GIDs
- **`CAP_SETPCAP`** – Modify process capabilities
- **`CAP_SETUID`** – Make arbitrary manipulations of process UIDs
- **`CAP_SYS_CHROOT`** – Change the root directory with `chroot`

### 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_WRITE` lets the container write audit records for compliance and monitoring.
- **File and ownership operations** – `CAP_CHOWN`, `CAP_FOWNER`, `CAP_FSETID`, and `CAP_DAC_OVERRIDE` enable necessary file permission modifications.
- **Process management** – `CAP_KILL` supports signal handling, while `CAP_SETUID` and `CAP_SETGID` allow user and group ID changes inside the container.
- **Network functionality** – `CAP_NET_BIND_SERVICE` permits binding to privileged ports, and `CAP_NET_RAW` supports raw socket operations required by many networking tools.
- **Device and filesystem control** – `CAP_MKNOD`, `CAP_SETFCAP`, `CAP_SETPCAP`, and `CAP_SYS_CHROOT` provide 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`](https://github.com/apple/container/blob/main/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:

```bash
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`:

```bash
container run --cap-add NET_ADMIN --rm alpine ip link set lo down

```

The following syntax variations are all valid:

```bash
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:

```bash
container run --cap-drop CHOWN --rm alpine chown 100 /tmp

```

This command produces the expected permission error:

```text
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:

```bash
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:

```bash
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`](https://github.com/apple/container/blob/main/docs/how-to.md)** – The “Control Linux capabilities” section documents the default list and provides CLI usage examples.
- **[`Sources/Services/ContainerAPIService/Client/Flags.swift`](https://github.com/apple/container/blob/main/Sources/Services/ContainerAPIService/Client/Flags.swift)** – Implements the parsing logic for `--cap-add` and `--cap-drop`, including case-insensitive matching and optional `CAP_` prefix handling.
- **[`Tests/IntegrationTests/Run/TestCLIRunCapabilities.swift`](https://github.com/apple/container/blob/main/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-add`** to grant additional capabilities and **`--cap-drop`** to remove defaults; the CLI is case-insensitive and accepts names with or without the **`CAP_`** prefix.
- The **`ALL`** keyword overrides the entire set, and operations are applied with **adds taking precedence over drops**.
- Definitions live in **[`docs/how-to.md`](https://github.com/apple/container/blob/main/docs/how-to.md)**, parsing logic in **[`Flags.swift`](https://github.com/apple/container/blob/main/Flags.swift)**, and verification in **[`TestCLIRunCapabilities.swift`](https://github.com/apple/container/blob/main/TestCLIRunCapabilities.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.