Create a gist now

Instantly share code, notes, and snippets.

Automatic Git commit signing with GPG on OSX
# In order for gpg to find gpg-agent, gpg-agent must be running, and there must be an env
# variable pointing GPG to the gpg-agent socket. This little script, which must be sourced
# in your shell's init script (ie, .bash_profile, .zshrc, whatever), will either start
# gpg-agent or set up the GPG_AGENT_INFO variable if it's already running.
# Add the following to your shell init to set up gpg-agent automatically for every shell
if [ -f ~/.gnupg/.gpg-agent-info ] && [ -n "$(pgrep gpg-agent)" ]; then
source ~/.gnupg/.gpg-agent-info
export GPG_AGENT_INFO
else
eval $(gpg-agent --daemon --write-env-file ~/.gnupg/.gpg-agent-info)
fi
# Enables GPG to find gpg-agent
use-standard-socket
# Connects gpg-agent to the OSX keychain via the brew-installed
# pinentry program from GPGtools. This is the OSX 'magic sauce',
# allowing the gpg key's passphrase to be stored in the login
# keychain, enabling automatic key signing.
pinentry-program /usr/local/bin/pinentry-mac
# Uncomment within config (or add this line)
use-agent
# This silences the "you need a passphrase" message once the passphrase handling is all set.
# Use at your own discretion - may prevent the successful interactive use of some operations.
# It is working fine for my use cases though.
batch
# A quick outline of what must be done to get everything working.
# 1) Install the dependencies.
brew install gnupg gpg-agent pinentry-mac
# 2) Configure git to automatically gpgsign commits. This consists of
# pointing git to your signing key ID, and then enabling commit
# automatic signing.
git config --global user.signingkey <YOUR-SIGNING-KEY-PUB-ID>
git config --global commit.gpgsign true
# 3) Configure the GPG components (see above for relevant examples):
# ~/.gnupg/gpg.conf
# ~/.gnupg/gpg-agent.conf
# 4) Start the daemon and configure your shell (see above for example in .profile).
# ~/.bash_profile | ~/.zshrc
# Don't forget to upload your public key to Github!
# https://github.com/blog/2144-gpg-signature-verification
# Note: There needs to be a three-way match on your email for Github to show
# the commit as 'verified': The commit email, github email, & the email associated with the public key
# Learn about creating a GPG key and the knowledge behind these commands here:
# https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work
@bmhatfield
Owner

The high level "connection diagram" for each part:

git -> gpg -> shell/env variable -> gpg-agent -> pinentry -> keychain
@justindowning

Thanks for posting this! Two small suggestions/changes:

  1. I use Boxen, so Homebrew is installed in a different location. For ~/.gnupg/gpg-agent.conf I was able to use pinentry-program $HOMEBREW_ROOT/bin/pinentry-mac making the config more portable.
  2. I had to amend the gpg-agent command on startup: eval $(gpg-agent --daemon --options ~/.gnupg/gpg-agent.conf --write-env-file ~/.gnupg/.gpg-agent-info)
@bcomnes
bcomnes commented Apr 6, 2016

Why do you use gpg instead of gpg2 or gnupg21? It comes with gpg-agent, pinentry as deps.

EDIT: My bad, pinentry-mac is does not come with the pinentry package.

@bcomnes
bcomnes commented Apr 6, 2016

I came up with a slightly different recipe, using the latest version of gpg (2.1) and slightly less bash glue around the agent. https://gist.github.com/bcomnes/647477a3a143774069755d672cb395ca Thanks for the writeup! It was helpful :)

@bmhatfield
Owner

@bcomnes - no particular reason on the gnupg choice. Just what I was used to. Thanks for sharing your workflow! Really the goal here is to highlight the pieces folks might need, so they can adapt them to their relevant approach.

@rpereira
rpereira commented Apr 8, 2016

@bmhatfield I've used this and it keeps me asking for the passphrase on every commit.

@bmhatfield
Owner

@ruiafonsopereira - sorry to hear that. The goal of this was more to try to give you all the pieces you needed to make this work, since it took me a little while to find them - you may have to adapt to your local environment. I wrote comments in each file with the intent of highlighting areas where you might do that. Some ideas I had to help troubleshoot: the .profile might not be sourced, or perhaps you didn't check "save in keychain" in the pinentry program, or perhaps gpg is installed in a way that it's looking for a different path, etc. Good luck!

@davisonio

Thank you!

@danieleggert

You can do all of this without any of this glue: https://gist.github.com/danieleggert/b029d44d4a54b328c0bac65d46ba4c65

@lenage
lenage commented Aug 1, 2016

Thanks @danieleggert , it works like charm! 😄

@takutaku947

I countered this error on your config:
"Inappropriate ioctl for device"
Solution:
Write "export GPG_TTY=$(tty)" in ~/.profile and restart.

@pustovalov

Thx

@PurpleBooth

Thanks! This is fantastic.

@aforty
aforty commented Dec 11, 2016

This is fantastic, thank you!

@loustler
loustler commented Jan 26, 2017 edited

Thanks guys.

I spent so many time to find solution for solve my problem.

Your solution is very fantastic.

@Necmttn
Necmttn commented Mar 11, 2017 edited

THANK YOU !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment