Signing your Git commits with GPG
Guillaume Briday
3 minutes
On Git, there's a way to prove that you are indeed the author of a commit, allowing others to verify that it comes from a trusted source. Today, we are going to see how to set up this functionality.
To sign commits, we will use GPG keys. Similar to SSH, we need to generate a private key and a public key for the client and the server.
Installation on macOS
To use the commands necessary for generating keys and reading them, you need to install the GPG suite:
$ brew install gnupg
Generating a key
$ gpg --full-generate-key
You'll be asked several questions:
For the key type, choose RSA and RSA
, option 1
.
Select a key size, and we recommend choosing the maximum, which is 4096
for better security.
You can choose a key expiration period, but personally, I prefer not to set an expiration date.
Confirm the information and then provide your name and email address.
Finish the configuration by typing O
and pressing enter
.
Set a strong
and unique
passphrase!
Your key is now generated, as indicated in the output.
Integration with Git
You can list your keys with the following command:
$ gpg --list-secret-keys --keyid-format LONG [email]
sec rsa4064/8180D3DC11D47453 2018-11-11 [SC]
CA67091517BC824B498858CD8180D3DC11D47453
uid [ultimate] demodemo <[email protected]>
ssb rsa4064/BA579BCEB3343AB0 2018-11-11 [E]
You can generate as many keys as needed, and they will all appear in this list. You can add an email
at the end of the command to filter only the keys matching that address.
The part we are interested in is the key ID, which in this example is CA67091517BC824B498858CD8180D3DC11D47453
.
This is what allows us to link Git with our key.
To manage GPG keys with Git globally:
$ git config --global gpg.program gpg
$ git config --global user.signingkey [key-id]
$ git config --global commit.gpgsign true # Optional
Replace [key-id]
with your key ID, in my case CA67091517BC824B498858CD8180D3DC11D47453
.
This ID is not private, and you can share it in dotfiles, for instance.
If you do not wish to sign every commit, you can also do so using the -S
flag with the git commit
command.
To avoid compatibility issues with GPG, we need to indicate in an environment variable the terminal output. To do this, add the following line to the top of your ~/.zshrc
or ~/.bashrc
:
export GPG_TTY=$(tty)
Now, when you try to make a commit in a version-controlled project, Git will ask for the passphrase you set for this particular key. Once validated, the commit will be saved and signed.
Associating the key with your GitHub or GitLab account
To link the signature of your commit with your public key, GitHub or GitLab needs to know your public key, which you can find with this command:
$ gpg --armor --export [key-id]
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQIJBFvospYBD+DlqSwnGncaMelPeY948Ek/yzyNUh0hSVOcHG6QORcOeQUZFTbV
MfE5f1mMckvGQZ8qSGQbW/mLOlkKxHMI6T7VGXhk0X/IbjnQAYeLN+CMTUxjNwaq
# ...
JZoICDtDf6/2QUoQVM/8n36pj5PzgLggWHAlifrF852Z0lDzfZt7EkTAYoYj9zPM
6m/Yhg2dkWMG36B37Hha0MEeew==
=rCa6
-----END PGP PUBLIC KEY BLOCK-----
Copy everything from -----BEGIN PGP PUBLIC KEY BLOCK-----
to -----END PGP PUBLIC KEY BLOCK-----
and add the key to your GitHub account in Settings > SSH and GPG keys
or to your GitLab account in Settings > GPG Keys
.
Bonus: GPG agent
If you've set a passphrase, Git will ask for it at every commit. This is not very convenient and will probably discourage you from signing your commits.
Luckily, there is a solution. Like with SSH keys, you can use an agent that keeps the passphrase and fills it in for you during a session.
To start the GPG agent in the background:
$ gpg-agent --daemon
You can also override the default configuration to set the session duration.
To do this, create the file ~/.gnupg/gpg-agent.conf
:
default-cache-ttl 28800
max-cache-ttl 28800
The duration is in seconds. In my case, the passphrase will be requested every eight hours.
Restart the gpg-agent
to apply the changes:
$ gpg-agent --daemon restart
Your passphrase will be requested one last time to be saved in the agent.
Conclusion
Now, on GitHub for example, you should see Verified
in the list of your commits.
You have no more excuses for not signing your commits now :)
Thank you!