How Container Manages Linux Capabilities and Security Boundaries: A Deep Dive into Apple's Runtime

Apple's container project implements a defense-in-depth security model that combines OCI-compliant Linux capability filtering with mandatory LSM lockdown and per-container lightweight VM isolation to enforce strict security boundaries between workloads and the host system.

Apple's open-source container repository provides a secure runtime for running Linux containers on macOS by meticulously managing Linux capabilities and security boundaries. The system processes capability modifications through a validated parsing pipeline before applying a three-stage calculation algorithm to determine the effective capability set. These controls operate within each container's dedicated lightweight VM, which launches with hardened kernel arguments enabling multiple Linux Security Modules (LSMs) to enforce kernel-level policies.

Parsing --cap-add and --cap-drop Flags

The CLI interface defines capability modification flags in Sources/Services/ContainerAPIService/Client/Flags.swift at lines 170 through 235. The --cap-add and --cap-drop flags accept comma-separated lists of capability names such as CAP_NET_RAW or the special keyword ALL.

Validation occurs in Sources/Services/ContainerAPIService/Client/Parser.swift within the Parser.capabilities method at lines 1019 through 1033. This method normalizes input strings to uppercase and validates each capability name against the CapabilityName enum provided by the containerization package, ensuring only recognized Linux capabilities are processed.

// Example CLI usage adding all capabilities then dropping network raw
$ container run --cap-add ALL --cap-drop CAP_NET_RAW myimage

Calculating Effective Capabilities in RuntimeService

The effectiveCapabilities method in Sources/Services/RuntimeLinux/Server/RuntimeService.swift (lines 1169 through 1196) implements a deterministic three-stage algorithm to compute the final capability set.

Stage 1: Initialize the capability set with OCI default capabilities unless ALL is present in the drop list, in which case start with an empty set. Stage 2: If ALL is present in the add list, replace the entire set with all available capabilities; otherwise, add only the specifically requested capabilities. Stage 3: Remove any explicitly dropped capabilities from the set, excluding the ALL keyword itself.

// Simplified logic from RuntimeService.swift
func effectiveCapabilities(capAdd: [String], capDrop: [String]) throws -> LinuxCapabilities {
    var caps = Set<CapabilityName>()
    
    // Stage 1: OCI defaults or empty if ALL is dropped
    caps = capDrop.contains("ALL") ? [] : Set(Containerization.LinuxCapabilities.defaultOCICapabilities.effective)
    
    // Stage 2: Add ALL or specific capabilities
    if capAdd.contains("ALL") {
        caps = Set(CapabilityName.allCases)
    } else {
        for name in capAdd { caps.insert(try CapabilityName(rawValue: name)) }
    }
    
    // Stage 3: Remove dropped capabilities
    for name in capDrop where name != "ALL" {
        caps.remove(try CapabilityName(rawValue: name))
    }
    
    return LinuxCapabilities(capabilities: Array(caps))
}

OCI Default Capability Set

The foundation for capability calculations originates in Containerization.LinuxCapabilities.defaultOCICapabilities, referenced at line 1179 in Sources/Services/RuntimeLinux/Server/RuntimeService.swift. This constant provides the standard OCI-compliant default capability set that containers receive unless explicitly modified by drop or add operations. The implementation adheres to the Open Container Initiative runtime specification, ensuring compatibility with standard container expectations while maintaining the principle of least privilege.

LSM Lockdown and Kernel Security Modules

When launching the sandbox VM, the runtime injects mandatory kernel arguments at lines 162 through 166 in Sources/Services/RuntimeLinux/Server/RuntimeService.swift. The argument lsm=lockdown,capability,landlock,yama,apparmor enables a comprehensive chain of Linux Security Modules that enforce mandatory access controls beyond discretionary permissions.

This configuration activates Lockdown mode for kernel integrity protection, the Capability module for POSIX capability enforcement, Landlock for unprivileged filesystem sandboxing, Yama for process ptrace restrictions, and AppArmor for profile-based mandatory access control. Together, these modules prevent privilege escalation attacks, unauthorized filesystem access, and cross-process memory inspection even if the container process possesses certain capabilities.

// Kernel arguments from RuntimeService.swift
let kernelArgs = ["lsm=lockdown,capability,landlock,yama,apparmor"]
let vm = try VirtualMachine(configuration: .init(kernelArgs: kernelArgs))

VM-Based Isolation Architecture

Each container executes within its own lightweight Linux VM, creating a hardware-level isolation boundary that separates CPU, memory, and device access from the host and sibling containers. This sandbox model, documented in docs/technical-overview.md, ensures that a compromised container cannot affect the host kernel or other containers despite sharing the same virtualized kernel environment.

Network isolation is achieved through macOS's vmnet virtual network interface, which attaches the sandbox VM to a segregated network stack. The runtime manages packet-filter rules to preserve network-level security boundaries while allowing necessary connectivity, as detailed in docs/how-to.md at section 204.

Summary

  • Capability management relies on a three-stage calculation in RuntimeService.effectiveCapabilities that processes OCI defaults, ALL keywords, and explicit capability modifications.
  • Input validation occurs in Parser.capabilities, which normalizes capability names and validates them against the CapabilityName enum.
  • LSM enforcement requires the kernel to boot with lsm=lockdown,capability,landlock,yama,apparmor, activating multiple mandatory access control modules.
  • Hardware isolation is provided by per-container lightweight VMs that separate workloads at the virtualization layer, complementing the capability and LSM security controls.

Frequently Asked Questions

How does container handle the ALL keyword in capability flags?

The ALL keyword serves as a meta-capability representing the complete set of Linux capabilities. When processing --cap-drop ALL, the runtime initializes the effective set to an empty array before applying additions. When processing --cap-add ALL, the runtime populates the set with every case from the CapabilityName enum, effectively granting full privileges before any specific drops are applied.

What Linux Security Modules does the container runtime enable?

According to the kernel arguments defined in RuntimeService.swift, the runtime enables Lockdown, Capability, Landlock, Yama, and AppArmor modules. This configuration provides defense-in-depth against kernel exploitation, unauthorized filesystem access, and cross-process attacks through mandatory access controls that operate independently of traditional Unix permissions.

How does the per-container VM model enhance security compared to traditional container runtimes?

Unlike traditional container runtimes that share the host kernel, Apple's implementation launches each container in a dedicated lightweight VM. This architecture provides hardware-level isolation for CPU and memory resources, ensuring that kernel exploits or container escapes cannot compromise the host system or other containers, even if the Linux capability and LSM restrictions were bypassed.

Where does the default capability set originate in the codebase?

The default capability set is defined by Containerization.LinuxCapabilities.defaultOCICapabilities, accessed at line 1179 in Sources/Services/RuntimeLinux/Server/RuntimeService.swift. This constant provides the OCI-standard default capabilities that containers receive unless explicitly modified through command-line flags or configuration.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →