How to use the GPG agent for SSH everywhere

encryptionenvironment-variablesmojavessh

On my system, I'm trying to set up SSH authentication through my GPG agent (installed via brew). So far, I have this working in my terminal thanks to adding the following lines to ~/.profile:

# Enable SSH support through GPG
export "GPG_TTY=$(tty)"
export "SSH_AUTH_SOCK=${HOME}/.gnupg/S.gpg-agent.ssh"

However, GUI applications (e.g. PyCharm) still use the SSH agent built into Mac (annoyingly). Is there any way/place I can use to set my SSH_AUTH_SOCK for my entire session? Ideally, I don't want to disable SIP to achieve my goal, and solutions like this don't seem to work.

For example, running import os; os.environ['SSH_AUTH_SOCK'] in PyCharm's builtin Python Console will still show /private/tmp/com.apple.launchd.whatever/Listeners instead of my auth sock. Likewise, it will not prompt for my GPG key passcode but instead go through the standard authentication flow.

This also persists in XCode, using a small sample program to get the value of SSH_AUTH_SOCK, so it's not PyCharm or a Python-only problem.

I'm currently running Mojave 10.14.4 on my system.

Best Answer

So, I managed to find a hacky solution that achieves the same goal. It appears (???) impossible to overwrite SSH_AUTH_SOCK, and I can't disable the builtin agent because I want to preserve SIP.

However, I can abuse symlinking to get my agent working reliably. Thanks to a nice article explaining how to leverage the YubiKey on a Mac (similar to my goal), I managed to create a LaunchAgent to symlink my agent to wherever SSH_AUTH_SOCK is pointing. So far I have yet to perform heavy testing with this, but it seems to be working okay.

Just in case the source link goes down, I created a file at ~/Library/LaunchAgents/link-ssh-auth-sock.plist with the following contents:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs>
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>link-ssh-auth-sock</string>
  <key>ProgramArguments</key>
  <array>
    <string>/bin/sh</string>
    <string>-c</string>
    <string>/bin/ln -sf $HOME/.gnupg/S.gpg-agent.ssh $SSH_AUTH_SOCK</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
</dict>
</plist>

This LaunchAgent replaces the Apple-generated socket (located in /private/tmp/...) with my own, but preserves Apple's environment variable. The symlink works, and is picked up in any application that supports using native SSH (in my case, PyCharm).

It's not a true solution to the issue (the socket is being symlinked, who knows what issues this could cause), but it at least works for the time being.

I'll keep trying to find a true solution to this problem, but in the meantime I'll share this answer just for any other curious souls with the same issue.