Dev

Signing your Git commits with GPG

Profil Picture

Guillaume Briday

3 minutes

List of Signed Commits
List of Signed Commits

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!

Simplify your time tracking with Timecop

Timecop is a time tracking app that brings simplicity in your day to day life.

Timecop projects