# How Apple Container Utilizes XPC for Interprocess Communication

> Discover how Apple container uses XPC for secure interprocess communication, enabling coordination between its API server, image management, and runtime components.

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

---

**Apple's `container` project leverages XPC (Cross-Process Communication) to isolate privileged operations across sandboxed helper services, enabling secure coordination between the API server, image management, networking, and per-container runtime components.**

The `container` repository implements a modular container runtime where distinct processes handle specific responsibilities. According to the technical overview in [`docs/technical-overview.md`](https://github.com/apple/container/blob/main/docs/technical-overview.md), the architecture relies on XPC to connect the `container-apiserver` with specialized helpers like `container-core-images`, `container-network-vmnet`, and `container-runtime-linux`.

## XPC Helper Services Architecture

The system decomposes container operations into isolated XPC services managed by **launchd**. Each helper runs in its own sandbox with minimal privileges, communicating through well-defined XPC APIs.

- **container-core-images** manages the local image store, exposing XPC methods for import, list, and delete operations.
- **container-network-vmnet** owns the vmnet virtual network device and allocates IP addresses, providing an XPC API for network resource requests.
- **container-runtime-linux** implements the per-container runtime for VM-backed containers, offering the most extensive XPC interface including bootstrap, process creation, and I/O handling.

## XPC Endpoint Creation and Transfer

When a client requires direct communication with a runtime helper, the system establishes an anonymous XPC connection through endpoint transfer. The server-side implementation in [`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift) creates the endpoint:

```swift
// RuntimeService.swift – createEndpoint
let endpoint = xpc_endpoint_create(self.connection)
let reply = message.reply()
reply.set(key: RuntimeKeys.runtimeServiceEndpoint.rawValue, value: endpoint)
return reply

```

This endpoint object transfers the capability to communicate with the helper back to the requesting client, bypassing the need for the client to know low-level Mach service details upfront.

## Client-Side XPC Connection Establishment

The client-side abstraction resides in [`Sources/Services/Runtime/RuntimeClient/RuntimeClient.swift`](https://github.com/apple/container/blob/main/Sources/Services/Runtime/RuntimeClient/RuntimeClient.swift). The `RuntimeClient` class handles the two-phase connection process: first obtaining the endpoint, then establishing the direct channel.

```swift
// RuntimeClient.swift – create()
let label = Self.machServiceLabel(runtime: runtime, id: id)
let client = XPCClient(service: label)
let request = XPCMessage(route: RuntimeRoutes.createEndpoint.rawValue)
let response = try await client.send(request)
let endpoint = response.endpoint(key: RuntimeKeys.runtimeServiceEndpoint.rawValue)!

let endpointConnection = xpc_connection_create_from_endpoint(endpoint)
let xpcClient = XPCClient(connection: endpointConnection, label: label)

```

To create a client and bootstrap a container, the CLI or consumer performs:

```swift
// Obtain a RuntimeClient for container "my-web-server"
let client = try await RuntimeClient.create(
    id: "my-web-server",
    runtime: "linux"
)

// Start the VM and guest agent (bootstrap)
await client.bootstrap(
    stdio: [nil, nil, nil],
    networkBootstrapInfos: networkInfos,
    dynamicEnv: ["PATH": "/usr/bin"]
)

```

## XPC Method Invocation and Process Management

Once connected, clients invoke runtime operations through strongly-typed XPC methods. The `RuntimeClient` packs arguments into `XPCMessage` objects and sends them via the established connection. For example, the bootstrap sequence:

```swift
let request = XPCMessage(route: RuntimeRoutes.bootstrap.rawValue)
request.set(key: RuntimeKeys.dynamicEnv.rawValue, value: encodedEnv)
request.set(key: RuntimeKeys.networkBootstrapInfos.rawValue, value: encodedInfos)
try await client.send(request)

```

For process creation and execution inside the container:

```swift
let procConfig = ProcessConfiguration(
    command: ["/usr/bin/python3", "app.py"],
    args: [],
    env: [:]
)

// Create the process in the container
try await client.createProcess("app", config: procConfig, stdio: [nil, nil, nil])

// Start the process
try await client.startProcess("app")

```

The helper service implements corresponding handlers in [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift), such as `startProcess`, which decodes incoming messages and manages the actual VM process lifecycle:

```swift
// Inside RuntimeService.swift – handling a startProcess request
public func startProcess(_ message: XPCMessage) async throws -> XPCMessage {
    self.log.debug("enter", metadata: ["func": "\(#function)"])
    defer { self.log.debug("exit", metadata: ["func": "\(#function)"]) }

    let pid = try message.decode(String.self, forKey: RuntimeKeys.id.rawValue)
    // … start the process in the VM …
    return XPCMessage()
}

```

## XPC Message Structure and Serialization

All XPC communications share a common foundation in the `ContainerXPC` module. Messages use enumerated keys defined in `RuntimeKeys` (such as `runtimeServiceEndpoint` and `dynamicEnv`) and support both JSON-encoded payloads and native XPC objects like endpoints. The `XPCMessage` extension provides convenience methods for encoding complex types like `SandboxSnapshot`, ensuring type safety across the interprocess boundary.

## Security and Isolation Benefits

The XPC architecture enforces security through **launchd** management and individual sandbox profiles for each helper. Because `container-core-images`, `container-network-vmnet`, and `container-runtime-linux` run as distinct processes with least-privilege access, a compromise in one component cannot directly access the resources of another. XPC also provides automatic connection cleanup when a helper crashes and validates helper binary signatures before establishing connections.

## Summary

- **XPC helper services** (`container-core-images`, `container-network-vmnet`, `container-runtime-linux`) run as isolated, sandboxed processes managed by `container-apiserver`.
- **Anonymous endpoint creation** in [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift) enables secure capability transfer from server to client without exposing Mach service details prematurely.
- **Two-phase connection** in [`RuntimeClient.swift`](https://github.com/apple/container/blob/main/RuntimeClient.swift) first obtains an endpoint, then establishes a direct XPC channel for command invocation.
- **Structured messaging** through the `ContainerXPC` module uses typed keys and supports both JSON and native XPC object serialization.
- **Security boundaries** enforced by launchd and sandbox profiles ensure fault isolation and privilege separation across container operations.

## Frequently Asked Questions

### What XPC services does Apple container use?

The `container` project uses three primary XPC helper services: `container-core-images` for image management, `container-network-vmnet` for virtual networking, and `container-runtime-linux` for per-container runtime operations. Each service exposes a specific XPC API consumed by the `container-apiserver` and client libraries, as documented in [`docs/technical-overview.md`](https://github.com/apple/container/blob/main/docs/technical-overview.md).

### How does container establish XPC connections between client and runtime?

The connection uses a two-phase endpoint transfer pattern. First, the client creates an `XPCClient` to the helper's Mach service and sends a `createEndpoint` request. The helper, implemented in [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift), creates an anonymous XPC endpoint and returns it. The client then converts this endpoint into a direct connection using `xpc_connection_create_from_endpoint`, establishing a private channel for subsequent commands.

### What security benefits does XPC provide in the container architecture?

XPC provides sandbox isolation, least-privilege access, and automatic cleanup. Each helper runs as a separate launchd-managed daemon with its own sandbox profile, preventing privilege escalation between components. XPC connections also validate code signatures and automatically terminate if a helper process crashes, ensuring that client applications cannot access resources beyond the granted XPC interface.

### Where is the XPC endpoint creation implemented in the source code?

The XPC endpoint creation logic resides in [`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift) (lines 21-28). The `createEndpoint` method generates an anonymous endpoint using `xpc_endpoint_create`, attaches it to a reply message using `RuntimeKeys.runtimeServiceEndpoint`, and returns it to the requesting client.