Companion Apps
Use your iPhone as a hardware SSH key with vmuxAgent and RemoteSignerPhone.
Overview
vmux includes two companion apps that turn your iPhone into a hardware SSH key for any Mac. Private keys are generated and stored in your iPhone's Secure Enclave — they never leave the device and can't be exported. When you run ssh on your Mac, the signing request is forwarded to your iPhone, where you approve it with Face ID or Touch ID.
This gives you hardware-backed SSH authentication without a physical security key. Your Mac never sees the private key.
Components
The system has two parts:
- vmuxAgent — a macOS menu bar app that acts as an SSH agent. It listens on a Unix socket (
~/.ssh/vmux-agent.sock) and forwards signing requests to your iPhone. - RemoteSignerPhone — an iOS app that holds your Secure Enclave keys and signs authentication challenges when you approve them.
The two apps communicate over Multipeer Connectivity, Apple's peer-to-peer protocol. They discover each other automatically when both devices are nearby on the same network or connected via Bluetooth.
Setup: RemoteSignerPhone (iPhone)
- Install RemoteSignerPhone on your iPhone.
- Open the app and tap Create Identity to generate a new Secure Enclave key pair. Give it a label (e.g., "Work Key").
- The app displays your public key in OpenSSH format (
ecdsa-sha2-nistp256 AAAA...). Tap Copy Public Key. - Add the public key to
~/.ssh/authorized_keyson each server you want to access:
echo "ecdsa-sha2-nistp256 AAAA...= Work Key" >> ~/.ssh/authorized_keysYou can create multiple identities. Each one generates a separate Secure Enclave key pair with its own public key.
Managing identities
- Enable/disable — Toggle an identity on or off without deleting it. Disabled identities won't be offered for signing.
- Rename — Change the label at any time.
- Delete — Permanently removes the Secure Enclave key. You'll need to regenerate and update your servers.
- Verify access — Confirms the Secure Enclave key is still accessible (prompts biometrics).
Setup: vmuxAgent (Mac)
- Install vmuxAgent on your Mac. It launches as a menu bar app with a key icon.
- Make sure your iPhone is nearby with RemoteSignerPhone open. The two apps connect automatically via Multipeer Connectivity. The menu bar icon changes to a filled key when connected.
- Click the menu bar icon and select Copy SSH_AUTH_SOCK Command. This copies:
export SSH_AUTH_SOCK=~/.ssh/vmux-agent.sock- Paste this into your terminal, or add it to your shell profile (
~/.zshrc,~/.bashrc) so it persists across sessions.
Once set, any SSH client in that shell will use vmuxAgent as its authentication agent.
Usage
With both apps running and connected:
- Run
ssh user@hoston your Mac. - The SSH client sends an authentication request to vmuxAgent via the agent socket.
- vmuxAgent forwards the signing request to your iPhone over Multipeer Connectivity.
- Your iPhone shows a notification with the request details (source device, destination host).
- Approve the request with Face ID or Touch ID.
- The signed response is returned to your Mac, and the SSH connection completes.
If you deny the request, the SSH connection fails with an authentication error.
You can also verify that the agent is working with:
ssh-add -lThis lists the public keys available through vmuxAgent, showing the fingerprint and label for each identity on your iPhone.
Background Wake
If your iPhone is locked or RemoteSignerPhone is in the background, vmuxAgent sends an APNs push notification to wake it. You'll see a notification on your iPhone:
SSH Sign Request Tap to open and approve the signing request.
Tapping the notification opens RemoteSignerPhone and restarts Multipeer Connectivity advertising. vmuxAgent retries the connection for up to 30 seconds after sending the push.
If the iPhone doesn't reconnect within that window, the SSH authentication fails. Open RemoteSignerPhone and try the SSH command again.
Key Caching
vmuxAgent caches the list of public keys from your iPhone. This means:
ssh-add -lreturns results immediately, even if your iPhone is temporarily out of range.- SSH can begin the authentication handshake using cached key identities.
- The actual signing still requires your iPhone to be reachable — cached keys only cover the identity advertisement step.
The cache persists across vmuxAgent restarts. When your iPhone reconnects, the cache is refreshed automatically.
Menu Bar
Click the key icon in your Mac's menu bar to see:
| Item | Description |
|---|---|
| Connection status | Shows "Connected to [device name]" or "Disconnected". |
| Key list | Each available identity with its label and SHA-256 fingerprint. |
| Copy SSH_AUTH_SOCK Command | Copies the export command to your clipboard. |
| Refresh Keys | Fetches the latest key list from your iPhone (requires active connection). |
| Quit | Stops vmuxAgent and removes the socket file. |
Security
- Private keys never leave the iPhone. They are generated in and bound to the Secure Enclave hardware. There is no export mechanism.
- Biometric approval required. Every signing request requires Face ID or Touch ID on the iPhone. There is no silent auto-approve mode.
- Encrypted transport. Multipeer Connectivity sessions use required encryption.
- Socket permissions. The agent socket at
~/.ssh/vmux-agent.sockis created with0600permissions (owner-only read/write). - No key material on Mac. vmuxAgent only sees public keys and signed responses. It never handles private key data.
Troubleshooting
| Problem | Solution |
|---|---|
| Menu bar shows "Disconnected" | Make sure RemoteSignerPhone is open on your iPhone and both devices are on the same network or have Bluetooth enabled. |
ssh-add -l returns "The agent has no identities" | Open RemoteSignerPhone and create an identity, then click Refresh Keys in the vmuxAgent menu. |
| SSH fails with "agent refused operation" | Check that you approved the request on your iPhone. If no prompt appeared, the phone may not have received the request — verify the connection status. |
| Push notification not received | Ensure notifications are enabled for RemoteSignerPhone in iOS Settings. The app must have been opened at least once to register for push notifications. |
ssh-add -l works but ssh fails | The server may not have your public key in authorized_keys, or the key algorithm (ecdsa-sha2-nistp256) may be disabled in the server's sshd_config. |
| Connection drops frequently | Multipeer Connectivity relies on local networking. Make sure both devices stay within Bluetooth/Wi-Fi range. |