DEV Community

Cover image for Signed Git commits in VS Code
Andreas
Andreas

Posted on • Edited on • Originally published at Medium

Signed Git commits in VS Code

The time had come to fix something that had been bugging me for a long time: Still making unsigned Git commits from VS Code.

TL;DR: Add "git.enableCommitSigning": true to settings.json of VS Code* after configuring your singing key ID and upload your public GPG key to your Git server.


I am a fan of green badges. Wherever possible, I’m trying to achieve them. I love when my browser shows the little green lock for websites served over HTTPS or when my taskbar shows the little green lock for an active VPN connection. Green badges indicate confidence and security. They give me the positive feeling, that the trustworthiness of someone or something was proved and certified. In times, where the Twitter account of Twitter CEO Jack Dorsey was hacked by simply duplicating his phones SIM card, it surely would be a good idea, to verify a tweet with more than just the senders phone number and reward a secure verification with a corresponding badge. So I try to provide as many green badges as possible for visitors, users and contributors of my work.

For most of my projects I use VS Code on Windows for creating and GitHub for publishing my code. The built-in Git integration in VS Code turned out to be extremely useful and fast for frequent Git commands. And now I wanted VS Code to sign my commits without additional effort or being interrupted to switch to the terminal.

Git supports signed commits for quite a while now (January 2012) and signed tags even longer. This means, Git provides the possibility to verify that commits are actually from a trusted source using the GNU Privacy Guard (GPG). GitHub marks signed commits with a green β€œverified” badge.

This is how it worked for me in VS Code on Windows:

Set up GPG

First you have to install GPG, if you don’t already have it. You can verify your installation (i.e. with Windows Power Shell) like this:



$ gpg --version
gpg (GnuPG) 2.2.17
libgcrypt 1.8.4


Enter fullscreen mode Exit fullscreen mode

If your system doesn't know them yet, you have to import your public and private keys (I assume you have them stored in files called public.key and private.key). If you don’t have a key pair, you can generate a new one. In that case, you can skip the import and directly jump to Set up Git. It's also possible to use your Keybase GPG key, if you have one (Stephen Rees-Carter wrote a nice article about it).



gpg --import public.key
gpg --import private.key


Enter fullscreen mode Exit fullscreen mode

Note: when importing the private key, a GUI window appears that asks for the corresponding passphrase you set when creating your key pair.

Set up Git

Now you can tell Git your signing key ID. It’s a 16-digit alphanumeric string that can be found with gpg --list-signatures (look for lines starting with β€œsig”).



git config --global user.signingkey 26A64778F76A7911


Enter fullscreen mode Exit fullscreen mode

If you want, you can tell Git to sign commits per default (since Git 2.0), so you don’t always have to add the -s flag in the command line:



git config --global commit.gpgsign true


Enter fullscreen mode Exit fullscreen mode

Note, that I use the --global flag here to apply these settings to all my local repositories. Of course you can apply these settings only to the current repository without it.

Set up GitHub

Now you have to give GitHub (or whatever Git server you’re using) your public key. You can print it with gpg --armor --export or get-content -path public.key (or open it with your favorite text editor) and copy it to your clipboard. Now go to GitHub, click on the top right menu, go to Settings > SSH and GPG keys > New GPG key and paste your key β€” it should look like this:



-----BEGIN PGP PUBLIC KEY BLOCK-----
...a lot of characters...
-----END PGP PUBLIC KEY BLOCK-----


Enter fullscreen mode Exit fullscreen mode

If everything worked correctly, you should see your GPG key like this:
New GPG key entry on GitHub (example)

New GPG key entry on GitHub (example)

Set up VS Code

Finally you have to tell VS Code to append the -s flag to the git commit command, to use signed committing now. Open the settings, search for β€œgpg” and check the box β€œEnables commit signing with GPG”.

Alternatively you can add this line to your settings.json :



"git.enableCommitSigning": true


Enter fullscreen mode Exit fullscreen mode

And that’s it! Now you can commit your changes in VS Codes Git integration and sign your work.

Note that you will be prompted for the passphrase of your private key at first.

Your commits now look like this in a GitHub repository under β€œcommits”:
Green badge indicating that this commit was signed with a verified signature

Green badge indicating that this commit was signed with a verified signature

This badge also appears under β€œreleases”, if the last commit of this release was signed:
Verified release on GitHub

Verified release on GitHub

Error: secret key not available

Well, would have been too easy if it worked at first try… unfortunately I had to deal with the following weird error message, that appeared always when I tried to commit using the -s flag:



$ git commit -am "a message" -s
gpg: skipped "26A64778F76A7911": secret key not available
gpg: signing failed: secret key not available
error: gpg failed to sign the data
fatal: failed to write commit object


Enter fullscreen mode Exit fullscreen mode

After some research, I found, that I had to tell Git the path to the GPG executable (for whatever reason) using the git config pgp.program setting:



git config --global gpg.program "C:\Program Files (x86)\gnupg\bin\gpg.exe"


Enter fullscreen mode Exit fullscreen mode

Note that the path may be a different one on your system.

After this, everything worked like a charm! Feel free to leave a comment, if you are facing other issues or you’d like to make me feel guilty because you already sign your commits for years :)


Edited: 2nd July 2021 (added TL;DR paragraph)
Originally published: 18th September 2019 on Medium

Latest comments (34)

Collapse
 
sp0ker profile image
RΓ©mi FLAMENT

You can define the key to use in your git config

git config --global user.signingkey AF5AD0.....
Enter fullscreen mode Exit fullscreen mode
Collapse
 
mitch1009 profile image
Mitch Chimwemwe Chanza • Edited

Thanks for this guide. i guess i don't have to make the same post i will share it. i have been using this feature on my account but a few week ago i came across a problem where every time i want to push changes to my repo it gives me this error:

  Git: fatal: the receiving end does not support --signed push
Enter fullscreen mode Exit fullscreen mode

i have to use the terminal and include

--signed=false
Enter fullscreen mode Exit fullscreen mode

for any push to work and it keeps my green badge status
any help on this guys.
Thanks for you help.

Collapse
 
smyja profile image
Smyja

great article, i'm going to try it on a mac.

Collapse
 
matiaslgonzalez profile image
MatΓ­as GonzΓ‘lez

Good article! Though I don't know if I'm understanding the subject incorrectly but I think the git commit flag needed to sign (in the sense of using you gpg keys to sign the commit) is -S and not -s. I'm assuming that the "git.enableCommitSigning": true option is adding -S correctly. My git man pages reads:

-s, --signoff
           Add Signed-off-by line by the committer at the end of the commit log message. The meaning of a signoff
           depends on the project, but it typically certifies that committer has the rights to submit this work under
           the same license and agrees to a Developer Certificate of Origin (see http://developercertificate.org/ for
           more information).
Enter fullscreen mode Exit fullscreen mode
-S[<keyid>], --gpg-sign[=<keyid>]
           GPG-sign commits. The keyid argument is optional and defaults to the committer identity; if specified, it
           must be stuck to the option without a space.
Enter fullscreen mode Exit fullscreen mode
Collapse
 
gizmecano profile image
P. Mergey • Edited

This kind of article is exactly what I expect to find on this platform: something which is supplementing documentation by adding some specific case studies (i.e. your last part about unavailability of secret key).

That being said, to come back to the subject, once the key has been created and the VSC editor settings have been properly configured, the recurring appearance of the Pinentry dialog window in order to type passphrase each time you are ready to commit something is particularly annoying (and it doesn't seem easy to define an convenient storage of this password currently).

Collapse
 
devmount profile image
Andreas

Thank you for your comment (I didn't get notified about it, seems like this is a general issue on dev.to for new comments on old articles)! I'm totally with you here - though you get used to it at some point, it's nevertheless additional effort.

I see if I can find a convenient way to save this password on a trusted device. I will update the article accordingly if I found something.

Collapse
 
16sweetyjain profile image
Sweety Jain

This post really saved me . I was quite frustrated why commit signing is not working irrespective of all the efforts.Thanks:)

Collapse
 
devmount profile image
Andreas

I'm happy it's working for you now πŸ‘πŸ»

Collapse
 
ryannorooz profile image
Ryan Norooz

just Created an account to come and thank you for the awesome articleπŸ‘
keep up the good stuff❀

Collapse
 
devmount profile image
Andreas

You're very welcome πŸ€— Will do!

Collapse
 
adarshmadrecha profile image
Adarsh Madrecha • Edited

Thanks for the guide. I have also written my 1st technical guide on the same topic with detailed screenshots for Windows and Gitlab - link.medium.com/LqSLButvuab

Collapse
 
shroomlife profile image
shroomlife πŸ„

Thank you very much!

Collapse
 
supermario_ai profile image
SuperMario

For me, I had to add a Carriage Return after -"----BEGIN PGP PUBLIC KEY BLOCK-----" and before "-----END PGP PUBLIC KEY BLOCK-----" to get it to work, but otherwise killer write up Fam! Thank you for this! β€πŸ’―