Introduction
This article shows how-to register the new Microsoft Open-SSH Client and it’s accompanying RSA Credential Manager (SSH-Agent Service) with Git for Windows, and how-to uplift your public/private RSA keypair file handling.
Problem(s) Description
Last I encountered an issue where when we install “Git for Windows” we are able to use the “git” verbs from a command shell in combination with an SSH connection. Even within our terminal windows launched within VS Code we are able to use these “git” verbs successfully.
However the problem lies in certain Visual Studio Code (vscode) extensions, (e.g. Gitlens) not being able to authenticate using our pre-saved RSA private keys to remote SSH repositories (e.g. Gitlab).
For example when we try to push our code (git push
) using one of these extensions we receive the following errors.

We also see the following error within the “Gitlens Output Channel”.
Failed to execute git {
"exitCode": 128,
"gitErrorCode": "RemoteConnectionError",
"gitCommand": "push",
"stdout": "",
"stderr": "git@gitlab.com: Permission denied (publickey).\r\nfatal: Could not read from remote repository.\n\nPlease make sure you have the correct access rights\nand the repository exists.\n"
}
We can overcome these issues by registering another custom Credential Manager for GIT over SSH.
For some of them this can even be achieved by overwriting the SSH client binary which “Git for Windows” uses. When doing so the accompanied Credential Manager would automatically kick in when trying to authenticate by using GIT over SSH.
Examples of custom Credential Managers include:
- Git Credential Manager for Windows (GCM), which has been replaced by the newer cross-platform compatible Git Credential Manager Core (GCM Core)
- Putty’s Pageant (plink.exe) by Simon Tatham – uses the SSH Client overwrite method
- Windows 10 – SSH Agent Service (OpenSSH), which is the one we will be integrating in this article – uses the SSH Client overwrite method
Another advantage why we chose to migrate from Pageant to OpenSSH is the ability to register our private RSA key with the SSH-Agent Service, and move it to a safe offline location/vault afterwards. So we actually don’t need to keep our private RSA key available on our live system.
Let’s get going, shall we? 😉
Install Git for Windows
We install Git for Windows using Microsoft’s new WinGet Windows Package Manager included in the latest editions of Windows 10. However you can always manually download the installer here.
PS C:\> winget install Git.Git
Install Open-SSH
We install the Windows 10 Optional Feature “OpenSSH Client” using PowerShell. This feature is available since Windows 10 1809.
Once installed all included binaries will have been installed in C:\Windows\System32\OpenSSH
.
PS C:\> Add-WindowsCapability -Online -Name OpenSSH.Client*
Generate a public/private RSA key pair
To authenticate against our remote repositories (e.g. gitlab) we will use a public/private RSA key pair. In case you haven’t generated a public/private RSA key pair before, you can now do so by using the newly installed binaries, see C:\Windows\System32\OpenSSH\ssh-keygen.exe
Remember your passphrase forward, as you will need it later on to unlock your private key from your keypair to use it.
PS C:\> ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (C:\Users\[USERNAME]/.ssh/id_rsa): C:\Users\[USERNAME]/.ssh/id_rsa
Enter passphrase (empty for no passphrase): *******************
Enter same passphrase again: *******************
Your identification has been saved in C:\Users\[USERNAME]/.ssh/id_rsa.
Your public key has been saved in C:\Users\[USERNAME]/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:T/5k......Bg [DOMAINNAME]\[USERNAME]@[COMPUTERNAME]
The key's randomart image is:
+---[RSA 3072]----+
*******OBFUSCATED*******
+----[SHA256]-----+
PS C:\>
Configure SSH-Agent Service
Since this service is by default configured to start manually, we will change this so it starts automatically upon booting our computer. We will also immediately be starting the service, all this using PowerShell.
PS C:\> Set-Service ssh-agent -StartupType Automatic
PS C:\> Start-Service ssh-agent
PS C:\> Get-Service ssh-agent | Format-Table Name, Status, StartType
Name Status StartType
---- ------ ---------
ssh-agent Running Automatic
PS C:\>
Register your private RSA key with the SSH-Agent Service
To prevent our private RSA key from being stolen we can register it with the SSH-Agent Service, and move it to a safe offline location/vault afterwards.
Once we then try to authenticate against a remote server using our public/private RSA key payer, the SSH-Agent Service will automatically present the private key for us instead.
PS C:\> ssh-add C:\Users\[USERNAME]\.ssh\id_rsa
Enter passphrase for C:\Users\[USERNAME]\.ssh\id_rsa:
Identity added: C:\Users\[USERNAME]\.ssh\id_rsa ([DOMAINNAME]\[USERNAME]@[COMPUTERNAME])
PS C:\>
If you want you can always verify with ssh-add -l
.
Once you’ve added your private RSA key (id_rsa), it is time to move it to a safe offline location/vault, so it can’t get stolen. Go ahead, Security First!
Register Open-SSH Client with Git for Windows
We will now set the SSH client binary from “Git for Windows” to OpenSSH by setting a user-scope environment variable within Windows. (see more)
By doing so the accompanied Credential Manager (SSH-Agent Service) would automatically kick in when trying to authenticate by using GIT over SSH.
PS C:\> Get-ChildItem Env:GIT_SSH
PS C:\> [System.Environment]::SetEnvironmentVariable('GIT_SSH','C:\Windows\System32\OpenSSH\ssh.exe', [System.EnvironmentVariableTarget]::User)
PS C:\>
If you want you can always verify the variable in "C:\Windows\system32\rundll32.exe" sysdm.cpl,EditEnvironmentVariables
.
EOF
“Voila!” You’ve now seen howto register the Microsoft Open-SSH Client with Git for Windows. We should now be able to successfully use VS Code extensions which use an RSA private/public key pair for authentication, such as Git over SSH.
And by doing so you were probably also able to raise your security bar, by now being able to store your RSA private key offline!