'VS Code / Bitbucket / SSH - Permission denied (publickey)

I'm trying to access bitbucket via ssh from vscode but always get permission denied (publickey).

SSH key(s) are located under ~\.ssh\, public key(s) are correctly setup in bitbucket/settings/security/sshkeys. The keys are tested and do work!

After booting, I can access my repository without problems from the windows command prompt and powershell but NOT from git bash or from vscode. Manually setting up ssh in git bash and starting vscode works though:

eval $(ssh-agent)
ssh-add /c/Users/username/.ssh/privatekey
code

My environment:

  • Windows 10 Enterprise (1803/17134.765)
  • Visual Studio Code (1.35.0)
  • git for windows (2.20.1.windows.1)
  • bitbucket via ssh
  • I think I'm using the ssh-agent that was introduced in one of the later Windows10 updates (not sure how to check, the windows ssh-agent service is running though).
  • my user folder (containing /.ssh) and the working copy of the repo are located on network drives

For me the problem boils down to one question: Why is vscode not using windows native, correctly setup ssh service and instead relying on git bash ssh agent?

Disclaimer: I spent hours reading threads about this topic and fiddling with settings. I suspect the problem to be related to the delayed deployment of network drives under Windows10 (a known issue). My windows group policy is set to wait for the network on boot/login.



Solution 1:[1]

Windows 10 allows using all default OpenSSH tools. However, git was throwing permission denied for every time when I tried to clone repositories from Github, Gitlab or Bitbucket over SSH. You need to perform a few tweaks to make it work.

  1. Make sure ssh-agent service enabled, or run in Powershell (as administrator):

Get-Service -Name ssh-agent | Set-Service -StartupType Manual

  1. ssh-agent
  2. ssh-add
  3. git config --global core.sshCommand C:/Windows/System32/OpenSSH/ssh.exe

Solution 2:[2]

In case someone is looking for an answer in mac

ssh-agent

ssh-add, after this command add your passphrase

Solution 3:[3]

In addition to the answer from Alexandr Pilgun some additional information that made the difference for me.

At step 4 I needed to provide double backslashes. VSCode complained that it could not find the ssh.exe. Using the double backslashes looks like this:

git config --global core.sshCommand C:\\Windows\\System32\\OpenSSH\\ssh.exe

I am using Windows 10.0.19042 Enterprise

Solution 4:[4]

I've had this for sooo long, and finally got to the bottom of it!

Note, I'm on Windows 10.

There are quite a few things that can be wrong. Some of those are fixed in the other answers. Also over course of time and various VSCode versions (or VS or GitHub Desktop or other programs using git), it has been different. An update to OpenSSL (which is automatic) was also the culprit once. In short, it's a mess to figure out what's going on.

I've got two more points to add that you could debug to figure out what's going on:

  1. related to PATH
  2. related to SSH_AUTH_SOCK

PATH

What we need to verify is that the git.exe used by your IDE is the same one you talk to on the terminal.

Whenever you're in Git Bash for Windows ("Bash" from now on), the PATH is different from the global PATH, as Bash inserts some paths, in my case

  • /mingw64/bin
  • /usr/bin
  • $HOME/bin (note that the paths starting with / are automatically prepended with the git installation folder, which by default is C:\Program Files\Git).

This can cause Bash and the IDE to resolve different git.exe, as PATH is used for that (and ssh.exe and ssh-add.exe). When I start my IDE, vscode in my case, it uses Windows' PATH to resolve git.exe and it found (in my setup) C:\Program Files\Git\cmd\git.exe. That's really unfortunate, because in the Bash terminal it finds /mingw64/bin/git.exe. You can find VSCode's git version from the very first line in the Git log in the Output panel. The bash one simply by running which git or where git (the latter will show you all of them on PATH).

I standardized on using the git in mingw64 by adapting the PATH accordingly.

Now if you have your ssh-agent enabled, you enter your passphrase in the terminal you might expect that from then on your IDE can resolve the passphrase too, as they use the same git.exe and thereby the same ssh.exe and ssh-add.exe.

SSH_AUTH_SOCK

The only thing that's truly important for any terminal or IDE to communicate with the ssh-agent is that it knows about it. That's solely conferred by the environment variable SSH_AUTH_SOCK (see the source code). If your IDE or terminal doesn't know about this environment variable, it's not going to find the passphrase in the ssh-agent.

It's important to realize how this environment variable is communicated among various programs. This is why many answers on SO will write it to a file ~/.ssh/agent.env and will read that on every bash terminal. But this has no effect on IDEs. This also is not a great solution if you combine it with Powershell:

  • which also doesn't write that .env file so bash wouldn't know about the ssh-agent
    • That's why -StartupType Automatic has no affect in the terminal
    • If you see multiple ssh-agents being spawn, this could be the reason.
  • Nor does Powershell read from the .env file, so it doesn't know about the bash-instantiated ssh-agent

You could confirm that this is in fact the issue by starting your IDE with the environment variable set, for instance by contrasting

  • code ./your-project (which gives permission-denied) with
  • export SSH_AUTH_SOCK=/tmp/ssh-...your/agent...; code ./your-project (which doesn't give permission denied, assuming ssh-client is up and populated, i.e. ssh-add has been called elsewhere).

You can find the socket of your agent by running ssh-agent, it'll print it (otherwise you haven't started it or added your passphrase yet). I'm just concluding along the way that ssh-agent is a binary that prints an executable bash, hence you can do eval `ssh-agent` .

Now the question is how you can get your VSCode to know about SSH_AUTH_SOCK. There are some ways listed above (and e.g. this), and those have worked for me sometimes, but not always/currently. I also don't see how that would work. Let me know if you do.

If you start vscode from the terminal which exports SSH_AUTH_SOCK, then it'll have access to the ssh-agent, but if you start vscode from the start menu or another shortcut, yeah, then it's not going to have the environment variable. You can't really make it a global environment variable in the System Environment at system startup because the value is assigned too late: only when running the ssh-agent.

So currently I do just that. I restart vscode from the vscode terminal. That's not really satisfactory. I'm considering changing the shortcut. One last question I have, to anyone who come so far: how is an IDE supposed to know about the SSH_AUTH_SOCK environment variable? I don't see it. VSCode doesn't seem to run ~./bashrc on startup, only for the terminals. Maybe this is behavior that varies over the VSCode versions?

Miscellaneous

Last things you could just: make sure your environment variables GIT_SSH and GIT_SSH_COMMAND are empty (that you haven't played with them, and forgotten about that). Same goes for the git config sshCommand. (I have mine pointed to C:/Program\\ Files/Git/usr/bin/ssh.exe).

Solution 5:[5]

the issue was resolved for me by using Windows Secure Channel library for HTTPS connections.

enter image description here

Solution 6:[6]

On Windows, I have to launch VS Code from bash.

> code

Then it inherits what I've got in .bashrc to load ssh agent with the keys I use. Slight inconvenience, but I usually have bash open as well if I'm working in VS Code anyway.

This is what JBSnorro has described in much more detail above.

Bottom of this page kind of recommends this approach: https://code.visualstudio.com/Docs/editor/versioncontrol

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Axel Anaya
Solution 2 Vibin
Solution 3 MrVirtualT
Solution 4
Solution 5 Danny
Solution 6 Clint Talbott