GPG SSH Configuration – Use GPG Auth Subkeys with pinentry in tmux

gpggpg-agentsshssh-agent

Context

I would like to use GPG authentication subkeys instead of SSH keys.

I would also like to use gpg-agent to manage password caching for these keys.

I am running in a headless environment, so I would like to use pinentry-curses for my password entry program, but I am fine with anything that works in a headless environment.

My development workflow is such that I am working in multiple tmux sessions and panes, and need to be able to git push from any of them.

Problem

The problem occurs when I attempt to do so. Instead of pinentry popping up in my current pane, it pops up in a random other pane (or sometimes perhaps no pane at all, but it's possible there are just too many to search through). To resolve this, I need to kill that pane and pinentry-curses and even then it still fails at times.

What I've Tried

Configurations I've Tried

My current configuration is as follows, though I've tried a plethora over the past couple weeks to attempt to get this working.

# ~/.zshrc

unset SSH_AGENT_PID
if [ "${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ]; then
  export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
fi

if [[ $SSH_AUTH_SOCK == /tmp/* ]]; then
    ln -sf $SSH_AUTH_SOCK $HOME/.ssh-agent-sock
    export SSH_AUTH_SOCK=$HOME/.ssh-agent-sock
fi

export GPG_TTY=$(tty)
gpg-connect-agent updatestartuptty /bye >/dev/null
# ~/.gnupg/gpg-agent.conf

pinentry-program /usr/sbin/pinentry-curses
default-cache-ttl 600
max-cache-ttl 7200
enable-ssh-support
# ~/.gnupg/gpg.conf

use-agent
# ~/.gnupg/sshcontrol

MYFINGERPRINTS
# ~/.ssh/config

Host localhost
ForwardAgent yes
AddKeysToAgent ask

Links I've Tried

Update: Working Configuration (thanks again to @SystematicFrank)

# ~/.zshrc

export GPG_TTY=$(tty)
# ~/.gnupg/gpg-agent.conf

pinentry-program /usr/bin/pinentry-curses
default-cache-ttl 600
max-cache-ttl 7200
enable-ssh-support
# ~/.gnupg/gpg.conf

use-agent
# ~/.gnupg/sshcontrol

MYFINGERPRINTS
# ~/.ssh/config

Host localhost
ForwardAgent yes
AddKeysToAgent ask
Match host * exec "gpg-connect-agent UPDATESTARTUPTTY /bye"

Best Answer

The problem is that you are calling gpg-connect-agent updatestartuptty every time you open a terminal, so pinentry points itself to the latest shell.

What you actually want is not the latest shell terminal, but the one you are connecting from (when calling ssh)

For that the easiest way is telling .ssh/config to execute the update command from the tty you are connecting. This is the magic line you are missing:

Match host * exec "gpg-connect-agent UPDATESTARTUPTTY /bye"
Related Question