# How to Use SSH Agent Forwarding with Containers (--ssh flag)

> Learn how to use SSH agent forwarding with containers using the `--ssh` flag. Securely access host SSH keys from inside your container without copying private credentials. Simplify your workflow today.

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

---

**Use the `--ssh` flag with `container run` or `container exec` to mount your host's SSH authentication socket at `/run/host-services/ssh-auth.sock` inside the container, allowing seamless access to host-loaded SSH keys without copying private credentials.**

The `apple/container` CLI provides native SSH agent forwarding through the `--ssh` flag, enabling containers to leverage your host's existing SSH authentication. This feature captures the `SSH_AUTH_SOCK` environment variable at runtime and establishes a dynamic bind mount, eliminating the need to embed private keys in container images or manually configure SSH credentials.

## How SSH Agent Forwarding Works in Container

When you append `--ssh` to a container command, the CLI reads the host's `SSH_AUTH_SOCK` path and configures the container runtime before the VM launches. This process involves three core components working together to ensure secure, transparent forwarding.

### Configuration and Flag Parsing

The `--ssh` flag is parsed in [`Sources/Services/ContainerAPIService/Client/Flags.swift`](https://github.com/apple/container/blob/main/Sources/Services/ContainerAPIService/Client/Flags.swift), which sets `containerConfig.ssh = true` in the configuration struct. This boolean is stored in [`Sources/ContainerResource/Container/ContainerConfiguration.swift`](https://github.com/apple/container/blob/main/Sources/ContainerResource/Container/ContainerConfiguration.swift) and persists throughout the container lifecycle to signal that SSH forwarding is requested.

### Runtime Mount Implementation

Before the container VM starts, [`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift) implements the forwarding through the `sshAuthSocketHostUrl` method. The service validates that `SSH_AUTH_SOCK` exists on the host; if missing, it logs a warning (`"ssh forwarding requested but no SSH_AUTH_SOCK found"`). When present, the runtime creates a volume mount mapping the host socket to `/var/host-services/ssh-auth.sock` inside the VM while injecting `SSH_AUTH_SOCK=/run/host-services/ssh-auth.sock` into the container's environment.

## Using the --ssh Flag in Practice

### Basic Container Execution

To forward your SSH agent into an interactive container, append `--ssh` to your run command:

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

```

Inside the container, verify the forwarding by checking the environment variable and listing loaded keys:

```bash
env | grep SSH_AUTH_SOCK

# Output: SSH_AUTH_SOCK=/run/host-services/ssh-auth.sock

ssh-add -l

# Lists your host-loaded SSH keys

```

### Cloning Private Repositories

SSH agent forwarding enables secure Git operations without embedding credentials in the container image:

```bash
container run -it --rm --ssh alpine:latest sh -c '
  apk add --no-cache openssh-client git &&
  ssh-add -l &&
  git clone git@github.com:my-org/private-repo.git
'

```

This approach uses the host's SSH agent to authenticate with GitHub or any private Git host, keeping private keys off the container filesystem.

### Executing Commands in Running Containers

For long-running containers started with `--ssh`, subsequent `exec` commands inherit the forwarded socket:

```bash
container exec dev -- ssh -T git@github.com

```

As implemented in [`Sources/ContainerCommands/Container/ContainerRun.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Container/ContainerRun.swift), the dynamic environment captured from `ProcessInfo.processInfo.environment` ensures that if your host's socket path changes between invocations, the next container launch automatically uses the updated source path while maintaining the static destination inside the container.

## Technical Implementation Details

The forwarding mechanism relies on [`ContainerRun.swift`](https://github.com/apple/container/blob/main/ContainerRun.swift) to propagate the host's `SSH_AUTH_SOCK` value into the container's dynamic environment dictionary. This design ensures that the bind mount source updates automatically if you log out and obtain a new authentication socket, while the destination path inside the container remains constant at `/run/host-services/ssh-auth.sock`. According to the repository's documentation in [`docs/how-to.md`](https://github.com/apple/container/blob/main/docs/how-to.md), this implementation follows the principle of least privilege by never persisting private keys inside the container VM, only forwarding the authentication socket connection.

## Summary

- The `--ssh` flag enables dynamic SSH agent forwarding by mounting the host's `SSH_AUTH_SOCK` into the container at `/run/host-services/ssh-auth.sock`
- Configuration flows from [`Flags.swift`](https://github.com/apple/container/blob/main/Flags.swift) to [`ContainerConfiguration.swift`](https://github.com/apple/container/blob/main/ContainerConfiguration.swift), with runtime implementation in [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift)
- The forwarding works with `container run`, `container start`, and `container exec` commands
- No private keys are copied into the container; only the authentication socket is forwarded
- The implementation automatically adapts to changes in the host's socket path between container launches

## Frequently Asked Questions

### What happens if SSH_AUTH_SOCK is not set on the host when using --ssh?

If the host environment variable `SSH_AUTH_SOCK` is not present, [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift) logs a warning message (`"ssh forwarding requested but no SSH_AUTH_SOCK found"`) and continues launching the container without the SSH mount. The container will not have access to SSH authentication, but the launch will not fail.

### Can I use SSH agent forwarding with container exec on a running container?

Yes. If the container was originally started with the `--ssh` flag, `container exec` commands inherit the same environment variables and mount points. This allows you to execute SSH commands in running containers without restarting them, as the dynamic environment persists through the container's lifecycle.

### Is the SSH socket path inside the container always the same?

Yes. While the host-side socket path from `SSH_AUTH_SOCK` can vary between system restarts or user sessions, the container always sees the socket at `/run/host-services/ssh-auth.sock`. The `RuntimeService` dynamically updates the bind mount source each time while keeping the destination constant, ensuring consistent behavior across container invocations.

### Does SSH agent forwarding work with private Git repositories?

Yes. Once forwarded, any SSH-aware tool inside the container—including `git`, `ssh`, and `scp`—can authenticate using the host's loaded keys. This is particularly useful for cloning private repositories or pushing changes without configuring deploy keys inside the container image, as documented in the [`docs/how-to.md`](https://github.com/apple/container/blob/main/docs/how-to.md) examples.