Cover image for Setting up git+ssh+gpg on Windows

Setting up git+ssh+gpg on Windows

qm3ster profile image Mihail Malo ・4 min read

Sometimes we all end up having to use Windows.
I was trying to avoid this, but it sneaks up on you.
So, how does one set up basic git with SSH authentication and GPG commit signing, for VS Code and command line?
Maybe I was spoiled by Linux community documentation, but I basically didn't get an answer. So, today we investigate!

Not in scope: We won't be:

  • generating the SSH identity with ssh-keygen -t rsa -b 4096 -C "YOUR.ACTUAL@MAIL.HERE"
  • or GPG key with gpg --generate-key,
  • nor adding them to https://github.com/settings/keys.

This article assumes you want to use your existing keys. But all these are well-documented. If you disagree and would like me to post a writeup on those, please leave a comment.

We will be using scoop instead of chocolatey, so that our setup is unprivileged and confined to the local user.

We'll assume you don't have anything installed.
So let's open up PowerShell (not as administrator) and begin:


# Enable powershell executables
Set-ExecutionPolicy RemoteSigned -scope CurrentUser
# Install scoop
iex (new-object net.webclient).downloadstring('https://get.scoop.sh')

# scoop uses aria2 for parallel downloads
scoop install aria2


scoop install git

Now, if you are on Windows 10 and don't follow Windows news,
run ssh -V and prepare to be shocked.
Since April 2018, Windows ships with OpenSSH!
Since we are going for a minimal setup here, we will not install our own version.
We still have to add an environmental variable for git to start using it, though:

[environment]::setenvironmentvariable('GIT_SSH', (resolve-path (scoop which ssh)), 'USER')

Don't forget to restart PowerShell / VS Code or wherever you plan to use git after this to load the environmental variable.

Now, let's continue configuring git:

git config --global user.name "YOUR ACTUAL NAME HERE"
git config --global user.email YOUR.ACTUAL@MAIL.HERE

Let's print the config to verify, it should look something like this:

git config -l --global
# credential.helper=manager

Now, let's add our actual key to ssh:

ssh-add YOUR\KEY\PATH\id_rsa

Note: If your key is located at ~/.ssh/id_rsa, and you have pshazz installed, you can (re)open a powershell, and pshazz will run ssh-add, adding it automatically (this will prompt you for the passphrase if you have one). I don't find it particularly valuable to keep your key there on Windows, so you can ssh-add it and then remove the file.

Now, assuming you will be using GitHub (similar for gitlab et al.), let's do a test connection (and save GitHub's signature, otherwise VS Code will get confused and silently fetch forever):

ssh -T git@github.com
# The authenticity of host 'github.com (' can't be established.
# RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
# Are you sure you want to continue connecting (yes/no)? yes
# Warning: Permanently added 'github.com,' (RSA) to the list of known hosts.

At this point, we have working git, but the commits will not get signed yet.


Now, the git package comes with a gpg executable, at:

# It's my first time writing powershell, any advice welcome
join-path (scoop prefix git) 'usr\bin\gpg.exe'

Let's temporarily alias it to gpg!

sal gpg (join-path (scoop prefix git) 'usr\bin\gpg.exe')

Aside: sal is an alias (wow, much meta) for Set-Alias.
But according to alias alias, alias isn't an alias for Get-Alias? 🤔🤔🤔

In my case it's a slightly older version than is available standalone.

scoop info gpg
gpg --version

But, once again, we're going for a minimal setup.
So, let's just jam our key right on in there.

# Enable signing all commits by default
git config --global commit.gpgsign true

Now, let's import our key:

gpg --import C:\YOUR\KEY\LOCATION\_SOMETHNG_-private.{key,gpg}

You may also want to ultimately trust your key:

$(echo trust; echo 5; echo y; echo quit) | gpg --command-fd 0 --edit-key YOUR.ACTUAL@MAIL.HERE

It is fine to remove your key file after this, it was imported into the gpg install.

Finally, let's install some more packages:

# the default bucket doesn't include GUI applications such as VS Code
scoop bucket add extras

# check for (self)updates
scoop update
scoop update *

# install the good nice things
scoop install vscode pshazz

🎉 We are done! 🎉

The result should look like this:

git config -l --global
# credential.helper=manager
# commit.gpgsign=true

gpg -K
# C:/Users/YOUR_NAME/AppData/Roaming/gnupg/pubring.kbx
# ------------------------------------------------
# sec   rsa4096 2017-10-18 [SC]
#       8E84465BB27D2E97F5B379C0D41763D409EF23A0
# uid           [ultimate] YOUR ACTUAL NAME HERE <YOUR.ACTUAL@MAIL.HERE>
# ssb   rsa4096 2017-10-18 [E]

To test signing, make a commit:

git init git-signature-test
pushd git-signature-test
echo "" > butts
git add butts
git commit -m Init
git log --show-signature
rm -r -fo git-signature-test

The output should include "Good signature from" followed by YOUR ACTUAL NAME HERE <YOUR.ACTUAL@MAIL.HERE>.

Edit: It seems like we installed the whole scoop mostly just to get git :)
Originally this article included installing your own OpenSSH and GPG, and even something from chocolatey, but after reading GitHub issues and experimenting, it turned out that just this is plenty. 🎉

Posted on by:


Editor guide