# How to Forward SSH Agent Sockets to Containers with the Apple Container Tool

> Forward SSH agent sockets to containers easily with the apple container tool. Use the --ssh flag to automatically mount your host's SSH auth socket inside the container for secure access.

- Repository: [Apple/container](https://github.com/apple/container)
- Tags: how-to-guide
- Published: 2026-06-12

---

**Use the `--ssh` flag when running container commands to automatically mount the host's SSH authentication socket at `/var/host-services/ssh-auth.sock` inside the container.**

The **apple/container** repository provides a first-class mechanism to forward SSH agent sockets from your host macOS system into Linux containers. This allows tools like `ssh`, `git`, and `ssh-add` running inside containers to authenticate using your host's SSH keys without ever copying private key material into the container filesystem.

## How SSH Agent Forwarding Works Internally

The implementation spans multiple Swift source files and follows a clear pipeline from environment detection to guest mount. When you append `--ssh` to any container command, the runtime executes three distinct phases.

### Step 1: Detecting the Host SSH_AUTH_SOCK

When a container starts, the command layer interrogates the host environment for the `SSH_AUTH_SOCK` variable. In [`Sources/ContainerCommands/Container/ContainerStart.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Container/ContainerStart.swift) (lines 91‑93) and [`Sources/ContainerCommands/Container/ContainerRun.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Container/ContainerRun.swift) (lines 131‑132), the code queries `ProcessInfo.processInfo.environment["SSH_AUTH_SOCK"]`. If the variable exists, its path is added to the dynamic environment dictionary that will be passed to the runtime service.

### Step 2: Propagating the Socket to the Guest Runtime

The runtime service receives the dynamic environment and validates the request. In [`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift), the `sshAuthSocketHostUrl` method (lines 55‑94) checks that `config.ssh` is enabled and extracts the socket path from the incoming environment. If present, it creates a URL pointing to the host socket file.

### Step 3: Mounting the Socket in the Container

When constructing the container configuration, the runtime fixes the guest path to `/var/host-services/ssh-auth.sock`. The service then adds a volume mount from the host socket URL to this guest path (lines 1028‑1035 in [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift)). Simultaneously, it injects the `SSH_AUTH_SOCK` environment variable into the container’s environment (lines 1074‑1075), ensuring processes inside the container reference the correct socket location.

## Using the `--ssh` Flag in Practice

The `--ssh` flag is defined in [`Sources/ContainerAPIService/Client/Flags.swift`](https://github.com/apple/container/blob/main/Sources/ContainerAPIService/Client/Flags.swift) (lines 191‑220) and toggles the `ContainerConfiguration.ssh` Boolean to `true`. You can append this flag to any container sub-command that accepts a configuration, including `run`, `exec`, and `build`.

Start an interactive container with SSH forwarding:

```bash
container run -it --rm --ssh alpine:latest sh

```

Inside the container, verify the forwarding works:

```console

# env | grep SSH_AUTH_SOCK

SSH_AUTH_SOCK=/var/host-services/ssh-auth.sock

# apk add --no-cache openssh-client git

# ssh-add -l

# git clone git@github.com:myorg/private-repo.git

```

For container builds that require SSH authentication (for example, cloning private Git repositories during the build), use:

```bash
container build --ssh myimage:latest .

```

## Dynamic Updates and Security

Because the socket path is resolved at container start time rather than cached, logging out and back in on the host—or changing the agent socket—does not require manual updates. The runtime always re-reads `SSH_AUTH_SOCK` when `--ssh` is present, ensuring the mount points to the current socket. Your private keys remain on the host; only the authentication socket is forwarded, minimizing exposure of sensitive material.

## Summary

- **Detection**: The tool checks `ProcessInfo.processInfo.environment["SSH_AUTH_SOCK"]` in [`ContainerStart.swift`](https://github.com/apple/container/blob/main/ContainerStart.swift) and [`ContainerRun.swift`](https://github.com/apple/container/blob/main/ContainerRun.swift) when `--ssh` is used.
- **Propagation**: `RuntimeService.swift::sshAuthSocketHostUrl` validates the configuration and extracts the socket path from the dynamic environment.
- **Mounting**: The runtime mounts the host socket to `/var/host-services/ssh-auth.sock` and sets the `SSH_AUTH_SOCK` environment variable inside the container.
- **Usage**: Append `--ssh` to any `container` command (run, exec, build) to enable seamless SSH agent forwarding.

## Frequently Asked Questions

### Is the forwarded SSH agent socket updated dynamically if I log out and back in?

Yes. The socket path is resolved fresh each time a container starts with the `--ssh` flag. Because [`ContainerStart.swift`](https://github.com/apple/container/blob/main/ContainerStart.swift) and [`ContainerRun.swift`](https://github.com/apple/container/blob/main/ContainerRun.swift) read `ProcessInfo.processInfo.environment["SSH_AUTH_SOCK"]` at runtime, changes to the host agent (such as logging out and creating a new agent) are automatically reflected in new containers without manual intervention.

### Can I use SSH forwarding with container builds?

Yes. The `--ssh` flag works with the `container build` command as well as `run` and `exec`. This allows build steps that clone private Git repositories or connect to remote servers via SSH to authenticate using your host's keys, as implemented in [`Flags.swift`](https://github.com/apple/container/blob/main/Flags.swift) where the flag populates the shared `ContainerConfiguration`.

### What happens if SSH_AUTH_SOCK is not set on the host?

If the `SSH_AUTH_SOCK` environment variable is absent on the host, the detection logic in [`ContainerStart.swift`](https://github.com/apple/container/blob/main/ContainerStart.swift) and [`ContainerRun.swift`](https://github.com/apple/container/blob/main/ContainerRun.swift) will not add a socket path to the dynamic environment. Consequently, [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift) will not create a mount, and the container will start without SSH forwarding capabilities. No error is thrown; the container simply runs without access to the host's SSH agent.

### Is the private key ever copied into the container?

No. The implementation only forwards the **socket** (`ssh-auth.sock`), not the private key files. The socket mount is created at `/var/host-services/ssh-auth.sock`, and the `SSH_AUTH_SOCK` environment variable points to this mount. Your private keys remain securely stored in the host's SSH agent, and the container only communicates with the agent through this forwarded socket.