aliquote.org

GPG on macOS

March 19, 2026

I’ve been a happy user of GPG on macOS and Linux for a while. On macOS, I used to use almost the same setup than on Ubuntu, except that I use pinentry for Mac (pinentry-mac installed with Homebrew).1 I got the same GPG key for a while, which was generated using GPGTools back when I was working on OS X. When I was back on macOS, I use my Linux setup and it worked smoothly. Now that I use Apple Mail exclusively, I want to be able to send signed (more rarely encrypted) emails in some cases. It was pretty easy to do under Neomutt:

set crypt_autoencrypt = no
set crypt_autopgp = yes
set crypt_autosign = no
set crypt_replysign = yes
set crypt_replysignencrypted = yes
set crypt_use_gpgme = yes
set crypt_verify_sig = yes
set pgp_self_encrypt = yes
set pgp_sign_as = 152E3E3F7C4CCE44
set pgp_use_gpg_agent = yes

I know the recommended and preferred way to sign your outgoing email is to rely on S/MIME, see here or there. The benefit of this approach is that you can sign your email from your iPhone too. However, I find much simpler to reuse my current setup, and for that I had to install GPG Suite with Mail plugin. I used to use it in the past, so it’s not really a problem to buy the upgraded version. After all, external certificates must also be bought from certified authorities.

Homebrew comes first in my $PATH so GnuPG is masking the gpg exec installed by the GPG Suite (in fact it is a symlink in /usr/local/bin to the gpg2 exec from MacGPG2). This is pretty easy to fix. However, the main issue seems to be that the GPG agent isn’t finding my private key, and I cannot sign my Git commit anymore. It took me some time to figure out that the GPG Suite relies on the standard location for the gnupg directory ($HOME/.gnupg), even if I have set an environment variable in shell profile for GNUPGHOME. Problem is that the GPG Suite is a macOS application and it is not aware of environment variables defined for the shell.

The solution was to kill the GPG agent, set a global environment variable using launchctl and move the $HOME/.gnupg directory back to its old place.

$ gpgconf --kill gpg-agent
$ launchctl setenv GNUPGHOME ~/.config/gnupg
$ mv ~/.gnupg ~/.config/gnupg

Upon launching GPG Keychain, it now uses the correct configuration and it finds the list of keys I have in my database. This is fine when using the GUI app. I don’t want to bypass the pinentry step.2 Now when it comes to signing Git commit from the command-line, the GPG agent complains that there’s no valid pinentry program since I originally set it to /usr/local/MacGPG2/libexec/pinentry-mac.app. It should have read:

pinentry-program /usr/local/MacGPG2/libexec/pinentry-mac.app/Contents/MacOS/pinentry-mac

Note that set-gpg-pinentry-program seems to do the same job as well.

[2026-03-20]
The pinentry seems to work smoothly outside the Terminal too.

img

♪ Amy Macdonald • Crazy Shade of Blue


  1. It is also possible to use touchid directly. ↩︎

  2. Something like gpg --full-gen-key --pinentry-mode loopback would alleviate the need for pinentry. ↩︎

See Also

» XDG Base Directory and macOS » I am a recovering Mac user » Hello macOS again » Ubuntu on a MacBook Pro » How I stopped worrying about the Mac