Forwarding a Secure Enclave SSH Agent Over Tailscale

close up photography of keys

Disclaimer: This post demonstrates that forwarding a Secure Enclave SSH agent is possible—not that you should do it. Exposing your SSH agent over a network increases your attack surface. If your Mac is compromised or the connection is intercepted, an attacker could use your keys to authenticate as you. Proceed with caution and understand the risks.

When working remotely, you might need to use SSH keys stored in your MacBook Pro’s Secure Enclave from a remote server. Since Secure Enclave private keys cannot be exported—they never leave the hardware—forwarding your local SSH agent socket is the only way to use them from another machine.

This guide assumes:

  • Both machines are on the same Tailscale network
  • You’re connecting from the remote server to your Mac

Setting Up Tailscale

Tailscale creates a private mesh network between your devices, making it easy to connect to your Mac from anywhere without exposing it to the public internet. Install Tailscale on both your Mac and the remote server, sign in with the same account, and they’ll be able to reach each other via stable 100.x.x.x IPs.

Enabling SSH on macOS

By default, macOS doesn’t accept incoming SSH connections. You need to enable Remote Login.

Via System Settings

  1. Open System SettingsGeneralSharing
  2. Enable Remote Login
  3. Choose “Allow access for” (all users or specific users)

Via command line

sudo systemsetup -setremotelogin on

Verify it’s running:

sudo systemsetup -getremotelogin

Restrict to Tailscale only (recommended)

Edit /etc/ssh/sshd_config and add:

ListenAddress 100.x.x.x

Replace with your Mac’s Tailscale IP, then restart:

sudo launchctl stop com.openssh.sshd
sudo launchctl start com.openssh.sshd

This prevents your Mac from accepting SSH connections from any network other than Tailscale.

Setting Up a Secure Enclave SSH Agent

macOS’s built-in ssh-agent doesn’t support Secure Enclave keys directly. You’ll need a third-party agent like Secretive.

Install Secretive

brew install --cask secretive

Generate a Secure Enclave key

  1. Open Secretive
  2. Click the + button to create a new key
  3. Choose “Secure Enclave” as the store
  4. Copy the public key to your servers’ ~/.ssh/authorized_keys

Configure SSH to use Secretive

Add to ~/.ssh/config on your Mac:

Host *
    IdentityAgent /Users/YOUR_USER/Library/Containers/com.maxgoedjen.Secretive.SecretAgent/Data/socket.ssh

Or export the socket path:

export SSH_AUTH_SOCK=/Users/YOUR_USER/Library/Containers/com.maxgoedjen.Secretive.SecretAgent/Data/socket.ssh

Verify it’s working:

ssh-add -l

Note the socket path—you’ll need it for the forwarding commands below.

Solution 1: SSH Local Forwarding

The simplest approach—forward the socket through an SSH connection.

From the remote server, connect to your Mac with -L:

ssh -L /tmp/agent.sock:/Users/YOUR_USER/Library/Containers/com.maxgoedjen.Secretive.SecretAgent/Data/socket.ssh user@your-mac.tailnet

In a separate terminal on the remote server:

export SSH_AUTH_SOCK=/tmp/agent.sock
ssh-add -l  # Verify it works

The socket only exists while the SSH connection is open.

Make it persistent

Add to your shell profile on the remote server:

export SSH_AUTH_SOCK=/tmp/agent.sock

Use tmux or screen to keep the SSH session alive, or set up autossh:

autossh -M 0 -f -N -L /tmp/agent.sock:/Users/YOUR_USER/Library/Containers/com.maxgoedjen.Secretive.SecretAgent/Data/socket.ssh user@your-mac.tailnet

Solution 2: socat Over Tailscale

Expose the socket directly over the Tailscale network using socat. No persistent SSH session required.

On your MacBook Pro

socat TCP-LISTEN:22122,bind=100.x.x.x,fork,reuseaddr UNIX-CONNECT:/Users/YOUR_USER/Library/Containers/com.maxgoedjen.Secretive.SecretAgent/Data/socket.ssh

Replace 100.x.x.x with your Mac’s Tailscale IP and YOUR_USER with your username.

On the remote server

socat UNIX-LISTEN:/tmp/agent.sock,fork TCP:100.x.x.x:22122 &
export SSH_AUTH_SOCK=/tmp/agent.sock
ssh-add -l  # Verify it works

Run as a launch agent (macOS)

Create ~/Library/LaunchAgents/com.user.ssh-agent-relay.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.user.ssh-agent-relay</string>
    <key>ProgramArguments</key>
    <array>
        <string>/opt/homebrew/bin/socat</string>
        <string>TCP-LISTEN:22122,bind=100.x.x.x,fork,reuseaddr</string>
        <string>UNIX-CONNECT:/Users/YOUR_USER/Library/Containers/com.maxgoedjen.Secretive.SecretAgent/Data/socket.ssh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
</dict>
</plist>

Load it:

launchctl load ~/Library/LaunchAgents/com.user.ssh-agent-relay.plist

Security Considerations

Both methods rely on Tailscale’s encrypted network, but:

  • SSH forwarding adds another layer of encryption and authentication
  • socat exposes the port to your entire Tailscale network—anyone on your tailnet with access to that port can use your keys

For most personal setups, either is fine. For shared tailnets, prefer SSH forwarding or add Tailscale ACLs to restrict access to the port.

Quick Reference

MethodCommand (from remote server)
SSHssh -L /tmp/agent.sock:/path/to/agent.socket user@mac
socatsocat UNIX-LISTEN:/tmp/agent.sock,fork TCP:mac-ip:22122

Then: export SSH_AUTH_SOCK=/tmp/agent.sock

Comments

Leave a Reply