# How Apple Container Handles Linux Capabilities and Security Isolation

> Discover how Apple's container secures Linux workloads with a three-layer isolation approach: OCI defaults, custom capability flags, and kernel LSM hardening. Learn about its security.

- Repository: [Apple/container](https://github.com/apple/container)
- Tags: deep-dive
- Published: 2026-07-08

---

**Apple's `container` runs each workload inside a lightweight Linux VM, enforcing security isolation through a three-layer mechanism that combines OCI default capabilities, user-provided** `--cap-add` **and** `--cap-drop` **flags, and kernel-level Linux Security Module (LSM) hardening with a strict** `lsm=lockdown,capability,landlock,yama,apparmor` **profile.**

The `apple/container` repository implements a declarative and defensive security model where fine-grained **Linux capabilities** replace full root privileges. Instead of relying solely on traditional user permissions, the runtime constructs a meticulously curated capability bitmap that the kernel enforces at the system call level, dramatically reducing the attack surface for containerized workloads.

## Architecture Overview: VM-Based Isolation

Every container spawned by the Apple `container` runtime executes within its own lightweight Linux VM. This virtualization boundary provides the foundation for **security isolation**, ensuring that privileged operations inside the container are strictly controlled by the host kernel.

The isolation strategy combines virtual machine boundaries with Linux kernel security features. When the VM boots, the kernel receives a hardened command-line argument string that activates multiple Linux Security Modules (LSMs) simultaneously. According to the source code in [`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift) at line 164, the kernel launches with:

```

lsm=lockdown,capability,landlock,yama,apparmor

```

This LSM stack ensures that capability boundaries are enforced while blocking accidental privilege escalation through disabled non-required interfaces.

## The Three-Layer Capability Security Model

Security isolation is implemented through three distinct layers that operate sequentially during container creation.

### Layer 1: OCI Default Capabilities

The runtime initializes each container with the minimal **OCI default capability set** defined by the Open Container Initiative specification. In [`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift) at line 1170, the `effectiveCapabilities` function seeds the initial capability bitmap using `Containerization.LinuxCapabilities.defaultOCICapabilities`.

The default set includes:
- `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`
- `CAP_SYS_CHROOT`

This minimal baseline ensures containers can perform basic operations without unnecessary privileges.

### Layer 2: User-Provided Flags

Users modify the default set through `--cap-add` and `--cap-drop` CLI flags. These arguments undergo strict validation and normalization in [`Sources/Services/ContainerAPIService/Client/Parser.swift`](https://github.com/apple/container/blob/main/Sources/Services/ContainerAPIService/Client/Parser.swift) at line 1025.

The `capabilities(capAdd:capDrop:)` function:
1. Converts all input to uppercase
2. Adds the `CAP_` prefix if missing
3. Validates each name against the `CapabilityName` enum
4. Raises `ContainerizationError` for invalid capability names

This validation occurs before the configuration reaches the VM, ensuring only legitimate Linux capabilities can be requested.

### Layer 3: Kernel LSM Hardening

The final layer occurs at VM boot time. As implemented in [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift), the kernel command line includes the strict LSM profile that enables `lockdown`, `capability`, `landlock`, `yama`, and `apparmor` modules simultaneously. This hardening ensures that even if a process somehow escapes its capability constraints, additional security policies prevent privilege escalation.

## How Effective Capabilities Are Computed

The [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift) file at line 1170 implements a three-step algorithm in the `effectiveCapabilities` function to determine the final capability set:

1. **Initialize**: Start with the OCI default capabilities, or an empty set if `ALL` is dropped
2. **Apply additions**: Process `--cap-add` entries, with `ALL` replacing the entire set
3. **Apply removals**: Remove individual capabilities specified in `--cap-drop`

The `ALL` sentinel acts as a wildcard. Using `--cap-add ALL` grants every capability, while `--cap-drop ALL` removes everything. The algorithm processes drops after adds, meaning `--cap-drop ALL --cap-add ALL` results in a full capability set.

This computed bitmap is then stored in the container's `ContainerConfiguration` (defined in [`Sources/ContainerResource/Container/ContainerConfiguration.swift`](https://github.com/apple/container/blob/main/Sources/ContainerResource/Container/ContainerConfiguration.swift) at line 57) and passed to the VM kernel as the effective capability mask for PID 1.

## Practical Examples

### Modifying Capabilities via CLI

Grant network administration privileges while removing the ability to change file ownership:

```bash
container run --cap-add NET_ADMIN --cap-drop CHOWN alpine ip link set eth0 up

```

Start with zero privileges and add only specific capabilities:

```bash
container run --cap-drop ALL --cap-add SETUID --cap-add SETGID alpine id

```

Drop a specific default capability:

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

```

### Swift Implementation: Computing Capabilities

The following Swift code demonstrates how the runtime computes the effective capability set:

```swift
import Containerization

// User input from CLI flags
let capAdd = ["NET_ADMIN", "ALL"]
let capDrop = ["CHOWN"]

// Parser normalizes and validates
let (normAdd, normDrop) = try Parser.capabilities(capAdd: capAdd, capDrop: capDrop)

// RuntimeService calculates final bitmap
let finalCaps = try RuntimeService.effectiveCapabilities(
    capAdd: normAdd,
    capDrop: normDrop)

// Result contains only permitted capabilities
print(finalCaps.capabilities)

```

### Configuring Process Security

When constructing a container configuration programmatically:

```swift
var containerConfig = ContainerConfiguration()
containerConfig.capAdd = ["ALL"]
containerConfig.capDrop = ["CAP_SYS_ADMIN"]

// Configuration propagates to the VM runtime
let proc = try RuntimeService.configureProcess(
    from: containerConfig,
    using: ociConfig)

```

## Key Implementation Files

- **[`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift)** (line 1170): Contains the `effectiveCapabilities` function that implements the three-step algorithm for computing final capability sets
- **[`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift)** (line 164): Assembles the kernel command line with the LSM hardening profile
- **[`Sources/Services/ContainerAPIService/Client/Parser.swift`](https://github.com/apple/container/blob/main/Sources/Services/ContainerAPIService/Client/Parser.swift)** (line 1025): Validates and normalizes `--cap-add` and `--cap-drop` arguments
- **[`Sources/ContainerResource/Container/ContainerConfiguration.swift`](https://github.com/apple/container/blob/main/Sources/ContainerResource/Container/ContainerConfiguration.swift)** (line 57): Defines the `capAdd` and `capDrop` properties that store user intent
- **[`docs/how-to.md`](https://github.com/apple/container/blob/main/docs/how-to.md)** (line 70): Documents the default capability list and CLI usage patterns

## Summary

- Apple `container` isolates workloads using lightweight Linux VMs with strict LSM profiles (`lsm=lockdown,capability,landlock,yama,apparmor`)
- **Default capabilities** follow the OCI specification, providing a minimal privileged baseline in [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift)
- **User customization** occurs through validated `--cap-add` and `--cap-drop` flags processed by [`Parser.swift`](https://github.com/apple/container/blob/main/Parser.swift)
- **Effective capability computation** follows a three-step algorithm: initialize with defaults, apply additions, then apply removals
- The kernel enforces the final capability bitmap at the syscall level, returning `EPERM` for unauthorized privileged operations

## Frequently Asked Questions

### What is the default capability set in Apple container?

The default set includes 14 capabilities defined by the OCI specification: `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`. These are seeded from `Containerization.LinuxCapabilities.defaultOCICapabilities` in [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift).

### How does the ALL sentinel work with capability flags?

Using `--cap-add ALL` grants every Linux capability, replacing the current set entirely. Conversely, `--cap-drop ALL` removes all capabilities. Because the algorithm processes drops after adds, the sequence `--cap-drop ALL --cap-add ALL` results in a container with full privileges, while `--cap-add ALL --cap-drop ALL` results in no privileges.

### What LSM modules does the container runtime use for isolation?

The VM kernel boots with `lsm=lockdown,capability,landlock,yama,apparmor`. This combination provides defense-in-depth: the `capability` module enforces traditional Linux capabilities, while `lockdown`, `landlock`, `yama`, and `apparmor` provide additional restrictions on privileged operations, ptrace, and filesystem access.

### Can I add virtualization capabilities to a container?

Yes, the `--virtualization` flag exposes nested virtualization (KVM) to the container, but this requires supported Apple Silicon hardware and a kernel compiled with the necessary configuration options. This is an exception to the minimal-default policy and must be explicitly requested.