3 minutes
How to Sign Commits With GPG on Mac OS X
Signed Git commits allows us to be sure that a commit has been made by the user (name and email) that the git log says.
To do so we’ll use a GPG key.
Generate a GPG key
First we need to install GPG:
brew install gnupg
Once it’s installed we’ll create the key:
gpg --full-gen-key
We’ll select RSA and RSA kind of key:
Please select what kind of key you want:
(1) RSA and RSA
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
(9) ECC (sign and encrypt) *default*
(10) ECC (sign only)
(14) Existing key from card
Your selection? 1
Then, we’ll chose 4096
:
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 4096
Requested keysize is 4096 bits
We’ll also chose to not expire:
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0)
Key does not expire at all
Is this correct? (y/N) y
After getting a verification step to ensure that everything is ok we’ll be asked for a password that will be requested every time we do a Git commit.
Git setup
We’ll need to get the GPG key ID:
gpg --list-secret-keys --keyid-format LONG <your_email>
The output will be:
gpg: checking the trustdb
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
sec rsa4096/DDDDAAAA11113333 2021-05-12 [SC]
1111792333392BE6F4431E32DA917BCEB3666622
uid [ultimate] Your Name <your.email@example.com>
ssb rsa4096/1234BF57VVVV3333 2021-05-12 [E]
We need the sec ID: DDDDAAAA11113333
.
With it we can then run this command to get the public key block:
gpg --armor --export DDDDAAAA11113333
Use this public key to configure your GitLab or GitHub account. You’ll find a place to add GPG keys in your user preferences.
Then we also need to setup our computer to be able to use that key:
git config --global user.signingkey DDDDAAAA11113333
git config --global gpg.program gpg
Add the following text to ~/.gnupg/gpg.conf
. Create the file if doesn’t exist:
no-tty
use-agent
Export the GPG_TTY
environment variable in your .zshrc
or .bash_profile
file:
export GPG_TTY=$(tty)
Then if we want to just sign the commits sometimes we can just add -S
parameter when doing a git commit
:
git commit -S -m "Test"
But if we want we can set up Git to do it always:
git config --global commit.gpgsign true
Common Errors
If you get the following error:
gpg: signing failed: Inappropriate ioctl for device
gpg: [stdin]: clear-sign failed: Inappropriate ioctl for device
Check if GPG_TTY
is well exported. Maybe you are missing a source ~/.zshrc
call.
If you get the following error when doing commits:
error: gpg failed to sign the data
fatal: failed to write commit object
To troubleshoot try first to execute: echo "test" | gpg --clearsign
, you might get something like:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
test
gpg: signing failed: No pinentry
gpg: [stdin]: clear-sign failed: No pinentry
If you get that you either need to install pinentry
:
brew install pinentry
or kill gpg agent after upgrading it:
gpgconf --kill gpg-agent