loading...
Cover image for How to Use GPG to Sign your Commits on Github, Gitlab, Bitbucket

How to Use GPG to Sign your Commits on Github, Gitlab, Bitbucket

shostarsson profile image Rémi Lavedrine ・6 min read

Git Security (2 Part Series)

1) How to Setup Multiple Ssh Keys for Multiple Github/Bitbucket accounts. 2) How to Use GPG to Sign your Commits on Github, Gitlab, Bitbucket

Photos from Jantine Doornbos on Unsplash

Hi everyone,

Everytime I get a new computer (which is not that often but often enough to write this), I am “struggling” with Git configuration for the different code repository accounts I have.

And everytime I have a new computer, I can’t remember what I did a few years/months ago to set it up properly.
So that post is as much for future me than it is for present you, as you are reading it. 🤔

After I set up my SSH Keys, I have to set up my signing identity on Git services.

Indeed if you don't sign your commits, everyone can impersonate on a commit.
That is why it is very important to sign your commit. 🖋️


tl;dr

To sum up what we are going to do, we are going to create a GPG Key and add it to your Git services as our identity and set up Git to use the proper GPG key and associate an e-mail with the GPG Key.

I will show you how to do that on GitHub, Bitbucket and GitLab.
Then I will explain how to define wich signing identity you want to use based on your project.

To sign a commit you create a Private/Public Key pair and you share the Public key with everyone that wants to verify your commit.
Your Public Key is actually shared through Github, Gitlab or Bitbucket to the people that want to verify your identity.

Each command to perform these actions is described below. 👨‍💻 ⬇️
Enjoy. 😎


🔑 GPG Keys Generation

  1. Here is the default command to create a GPG key.
gpg --full-generate-key

If you don't know what GPG stands for, you should have a look at it on Wikipedia.

  1. At the prompt, specify the kind of key you want, or press Enter to accept the default RSA and RSA.

    GitHub supports several GPG key algorithms you can use.

    • RSA
    • ElGamal
    • DSA
    • ECDH
    • ECDSA
    • EdDSA
  2. Enter the desired key size. I recommend the maximum key size of 4096.

  3. Enter the length of time the key should be valid. Press Enter to specify the default selection, indicating that the key doesn't expire. I recommend to have at most a 1 year expiration date.

  4. Enter your user ID information.

  5. Verify that your selections are correct.

  6. Type a secure passphrase.

  7. Save the secure passphrase for that key into your Password Manager of choice (I personaly use KeepassXC).

To check that everything goes properly, you can list the GPG keys you have on your device.

gpg --list-secret-keys --keyid-format LONG
/Users/hubot/.gnupg/secring.gpg
------------------------------------
sec   4096R/3AA5C34371567BD2 2016-03-10 [expires: 2017-03-10]
uid                          Hubot 
ssb   4096R/42B317FD4BA89E7A 2016-03-10

Here is a video that shows the whole process.

For that example, I will consider that we have a personal identity (e-mail) that we want to use on Github and Gitlab and a professional identity that we want to use on Github and Bitbucket.

Let sum it up in a table :

Service Identity e-mail Comment
Github Personal remi.lavedrine@perso.com Personal Identity on Github
Github Professional remi.lavedrine@pro.com Professional Identity on Github
Gitlab Personal remi.lavedrine@perso.com Personal Identity on Gitlab
Bitbucket Professional remi.lavedrine@pro.com Professional Identity on Bitbucket

I created all these keys for the purpose of that post.
Feel free to create the ones you need and then check that everyone is correct using the following command gpg --list-secret-keys --keyid-format LONG


✍️ Configure Git Identity and Signing Strategy

Now that we have GPG Key up and ready, we can configure Git to pick up the proper GPG key according to our identity.

🗺️ Global Configuration

You must declare a global configuration for your Git.

git config --global --edit

Add the default user :

[user]
    signingkey = 4B6598BF5707D5A4
    name = Remi Lavedrine
    email = remi.lavedrine@perso.com

Define your signing commit strategy (I do not recommand to automatically sign all commits 😉) :

[commit]
    gpgsign = true

So we have now our default Git identity.

🏙️ Local Configuration

To have much more control on our signing identity, we are going to define our identity project per project as soon as we are cloning a new repository.
Just move to the destination folder, and clone your repository (git clone git@github.com:thepracticaldev/dev.to.git for instance 😉).

Once you are in your repository folder, you can fire that command :

git config --local --edit

Or if you are not that comfortable with vi, you can just edit the ./.git/config file.

nano ./.git/config

And, just as for the global configuration, you just have to add the user and your signing commit strategy of choice.

[user]
    signingkey = 4B6598BF5707D5A4
    name = Remi Lavedrine
    email = remi.lavedrine@perso.com

[commit]
    gpgsign = true

Do it for every repository you are working with and want to sign your commits.


💭 Add the Keys to your Repositories Accounts

Everything is now setup properly locally.
So we have to add the SSH public keys to the services you are using.

  1. Let us list the GPG Keys available.
gpg --list-keys
sec   rsa4096/4B6598BF5707D5A4 2019-07-16 [SC] [expire : 2020-07-15]
      913C42CFA493DCF45FA65B464B6598BF5707D5A4
uid                [  ultime ] Rémi Lavedrine (Personal Identity on Github) <remi.lavedrine@perso.com>
ssb   rsa4096/425EA1013A372D16 2019-07-16 [E] [expire : 2020-07-15]

sec   rsa4096/943F54877369FBC9 2019-07-16 [SC] [expire : 2020-07-15]
      BD1318B04CEAB84DC5FB8BFA943F54877369FBC9
uid                [  ultime ] Rémi Lavedrine (Professional Identity on Github) <remi.lavedrine@pro.com>
ssb   rsa4096/61531E9B065DD712 2019-07-16 [E] [expire : 2020-07-15]

sec   rsa4096/D1495F54BE4ECF37 2019-07-16 [SC] [expire : 2020-07-15]
      9EB8C0816D7C607FC493F354D1495F54BE4ECF37
uid                [  ultime ] Rémi Lavedrine (Personal Identity on Gitlab) <remi.lavedrine@perso.com>
ssb   rsa4096/90055F33F5B23681 2019-07-16 [E] [expire : 2020-07-15]

sec   rsa4096/B788EC8FF8B4487C 2019-07-16 [SC] [expire : 2020-07-15]
      090D6265BB26DF44E3D84173B788EC8FF8B4487C
uid                [  ultime ] Rémi Lavedrine (Professional Identity on Bitbucket) <remi.lavedrine@pro.com>
ssb   rsa4096/659371B2F5F99CAB 2019-07-16 [E] [expire : 2020-07-15]
  1. And copy the one we want to use (Personal Identity on Github). On MacOS, it is pretty easy to copy a GPG Public key to the clipboard.
gpg --armor --export 913C42CFA493DCF45FA65B464B6598BF5707D5A4 | pbcopy

🐙 Github

  1. Let's login to your Github account and go to the account's settings.
    Github : Go to Settings

  2. Select "SSH and GPG Keys".
    Github : List GPG Keys

  3. Click on the "New GPG Key" button and paste the content of your clipboard to the Website and then click on "Add GPG Key".
    Github : Add GPG Key on Github Account

🤜 💥 🤛 You're good to go!!!

Here is a video that sums it up.

🦊 Gitlab

  1. Let's login to your Gitlab account and go to the account's settings.
    Gitlab : Go to Settings

  2. Navigate to the GPG keys tab, paste your public key in the "Key" box, save.
    Add GPG Key to Gitlab

🤜 💥 🤛 You're good to go!!!

🗑️ Bitbucket

On Bitbucket, signing commits works only on the on-premise version of the service (Bitbucket Server).

  1. Let's log in to your Bitbucket account and go to the account's settings.
    Bitbucket : Go to Settings

  2. Click GPG keys. > Add key.

  3. Paste the content of the GPG Public Key you have in your clipboard.

  4. Click on the "Add key" button to validate it.

🤜 💥 🤛 You're good to go!!!


🖋️ Sign Commits Using your GPG Key

Everything is configured now, both on your machine and on the services.
You can sign your commits.

To sign your commits, you just have to add a "-S" argument to your git commit command.

A signed commit will look like that :

git commit -S -m "My commit message"

You can then push your commit to GitHub, GitLab or Bitbucket and check that your commits are verified.

As explained in the configuration section, if you don't want to add the "-S" argument every time you commit you can edit the Git local configuration (git config --local --edit or git config --local commit.gpgsign true).


🖋️ Sign Tags Using your GPG Key

On Git, you can sign commits.
But you can also sign tags.

As for signing commit, you just have to add a "-s" argument to your git tag command.

A signed tag will look like that :

git tag -s -m "My tag message"

You can also verify your signed tag running the following command :

git tag -v mytag
    Verifies the signed tag

You can now create as much GPG Keys you want and add them to Github, Gitlab or Bitbucket and then configure your signing strategies locally and sign your commits or tags.

I hope that helps you.

Cheers 🍻

I found help for this post on the GitHub, GitLab and Bitbucket documentations.

Git Security (2 Part Series)

1) How to Setup Multiple Ssh Keys for Multiple Github/Bitbucket accounts. 2) How to Use GPG to Sign your Commits on Github, Gitlab, Bitbucket

Posted on by:

shostarsson profile

Rémi Lavedrine

@shostarsson

Software Dev turned Security Dev. Follow me on dev.to, twitch.tv/shostarsson or youtube.com/shostarsson

Discussion

markdown guide
 
 

Thanks for the article. You wrote that you don't recommend to sign all the commits. What do you recommend? Which commits would you sign and why?

 

I do not recommend to sign all of your commit on your global configuration because if you don't have a GPG key properly configured for a service that you are going to use you are going to encounter some problem.
Similarly if you are using a software to manage your git (like Gitkraken for instance), if you have a Global configuration that force signing all commits, you can have some problem.
That is why I think that you should force signing commit on a repo from repo strategy.

I hope that helps.