How to Forward SSH Agent and Sockets to Containers in Apple Container

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 tool provides first-class support for SSH agent forwarding through a dedicated CLI flag. This guide explains how to forward SSH agent and sockets to containers and examines the underlying implementation in the apple/container open-source repository.

Using the --ssh Flag to Forward SSH Agent

The simplest way to forward SSH agent and sockets to containers is the --ssh flag available on all container subcommands that accept runtime configuration. When enabled, the tool detects the host's SSH_AUTH_SOCK environment variable and mounts the corresponding Unix socket into the container.

Run a container with SSH forwarding enabled:

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

For build operations that require private repository access:

container build --ssh myimage:latest .

The flag is defined in Sources/ContainerAPIService/Client/Flags.swift (lines 191-220) and stores the value in ContainerConfiguration.ssh. According to the apple/container source code, this boolean triggers the full forwarding pipeline during container initialization.

How SSH Forwarding Works Under the Hood

The implementation follows a three-stage pipeline from CLI detection to guest mount creation.

Detecting the Host SSH Socket

When a container starts, the code checks ProcessInfo.processInfo.environment["SSH_AUTH_SOCK"] to locate the host's authentication socket. This detection occurs in ContainerStart.swift (lines 91-93) and ContainerRun.swift (lines 131-132). If the variable exists, its path is added to the dynamic environment passed to the VM guest.

Propagating the Socket to the Guest

In Sources/Services/RuntimeLinux/Server/RuntimeService.swift, the sshAuthSocketHostUrl method validates that config.ssh is true and retrieves the socket path from the dynamic environment (lines 55-94). This creates a URL pointing to the host socket that the runtime will mount into the container namespace.

Mounting the Socket and Injecting Environment Variables

When building the container configuration, the runtime adds a volume mount from the host socket URL to the fixed guest path /var/host-services/ssh-auth.sock (lines 1028-1035 in RuntimeService.swift). Simultaneously, it injects the SSH_AUTH_SOCK environment variable into the container's environment (lines 1074-1075), ensuring processes inside the container can locate the forwarded agent.

Verifying SSH Agent Forwarding

Once inside the container, verify the forwarding works by checking the environment variable and listing loaded keys:


# env | grep SSH_AUTH_SOCK

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

# apk add --no-cache openssh-client

# ssh-add -l

# Lists keys loaded in the host's SSH agent

You can now use SSH-based tools like git clone git@github.com:org/private-repo.git without copying private keys into the container.

Summary

  • The --ssh flag automatically forwards the host SSH agent to containers by mounting the socket and setting SSH_AUTH_SOCK
  • Implementation spans ContainerStart.swift, ContainerRun.swift, RuntimeService.swift, and Flags.swift
  • The socket mounts at /var/host-services/ssh-auth.sock inside the container with environment variable injection
  • Works with run, exec, build, and other container subcommands
  • Socket path is resolved at container start time, ensuring dynamic updates when the host agent changes

Frequently Asked Questions

What is the guest path for the forwarded SSH agent socket?

The container runtime mounts the host's SSH authentication socket at the fixed path /var/host-services/ssh-auth.sock inside the container. The SSH_AUTH_SOCK environment variable is automatically set to point to this location so tools like ssh, git, and ssh-add can locate the agent without manual configuration.

Does the --ssh flag work with container build commands?

Yes. The --ssh flag works with all container subcommands that accept configuration, including container build, container run, and container exec. When used with builds, it allows build steps to authenticate against private repositories using the host's SSH keys without embedding credentials in the image layers.

Is the SSH agent socket updated dynamically?

Yes. The socket path is resolved at container start time by reading the host's SSH_AUTH_SOCK environment variable in ProcessInfo.processInfo.environment. This means logging out and back in on the host, or changing SSH agents, does not require manual updates inside the container. Each invocation with --ssh re-reads the current socket path from the host environment.

How does the runtime validate SSH forwarding configuration?

The RuntimeService.swift validates the configuration by checking config.ssh before attempting to mount the socket. The Flags.swift file defines the --ssh CLI flag and stores it in ContainerConfiguration.ssh, which the runtime inspects in the sshAuthSocketHostUrl method. If the flag is not set, the runtime skips SSH forwarding entirely.

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 →