I've set up OpenSSH on various flavors of Linux tons of times. But I can't for the life of me get it functioning correctly on windows.

There seem to be two sides to the issue. The permissions and the key used by sshd/ssh-agent.


Every page I read has a different answer for the correct permissions. Some work, and sometimes the program complains about them.

From what I understand the keys should all be owned by SYSTEM, with read access for NT SERVICE\sshd and Full Control for Administrators and SYSTEM? (As I understand SYSTEM and Administrators represent root in Windows). I read in the documentation that the read access is only necessary if not using ssh-add/ssh-agent. I also configured the same permissions for the %USERPROFILE%/.ssh/authorized_keys file and added the .pub the Ed25519 key which is the one I'm using to try and connect, though I've also tried it with my own generated RSA key.

With the permissions set this way the program doesn't complain when adding keys to the agent or running the daemon. The only option I changed in sshd_config is the ListenAddress which was binding to, I set it to the machines local IP as SSH will only be used locally.


When I run sshd.exe with the -d option, I notice it importing the 4 default keys from %PROGRAMDATA%/ssh. When I added the ed25519.pub key to authorized_keys it was followed by HOSTNAME@workstation@HOSTNAME, HOSTNAME being my PC's hostname. Normally I would expected to see user@host. I tried creating my own key and adding it but when I run sshd.exe -d it never seems to use anything other than the default keys.

In the end, I'm unable to connect to the OpenSSH server, and the logs in %PROGRAMDATA%/ssh/Logs only seem to show the server starting. To sum up my questions: What are the correct permissions for the key files and authorized_hosts? Does the annotation in authorized_keys being wrong make a difference? Should I be adding all of the default keys .pub's into authorized_hosts? And last, what does sshd mean when it mentions those keys during startup (see log)? Shouldn't my own generated key just work as long as I add it to authorized_hosts?

debug1: sshd version OpenSSH_for_Windows_7.6, LibreSSL 2.6.4
debug1: private host key #0: ssh-rsa SHA256:and12LVkEqyXJ2gr0SxFEQObaSFF+Czlcnx2uFjZaJQ
debug1: private host key #1: ssh-dss SHA256:waeLdy4Sm3NT+zbwEMIhbfl8TLe6WeQ0MuZE07CzFQU
debug1: private host key #2: ecdsa-sha2-nistp256 SHA256:G8/7y/04cSE3EezTrcmpK4lRmJ5f5I/CDPcHaPzsv4o
debug1: private host key #3: ssh-ed25519 SHA256:Jvn9UjsbdzH54L/yvGYGfCzJQVIMiIWL5RETbaL2ACA
debug1: rexec_argv[0]='C:\\WINDOWS\\System32\\OpenSSH\\sshd.exe'
debug1: rexec_argv[1]='-d'
debug1: Bind to port 22 on
Server listening on port 22.

3 Answers 3


You seem to mix server hosts keys and your account public keys.

Server host keys are generated by Win32-OpenSSH in %PROGRAMDATA%/ssh on its first start. They are also given correct permissions, no need to modify them. These are the keys you see loaded as "private host key" in your log. That also indicates they have the correct permissions (otherwise they won't load).

Your account public keys go to %USERPROFILE%/.ssh/authorized_keys (or to %PROGRAMDATA%/ssh/administrators_authorized_keys for Administrator accounts). That file must have write access only for the account to which they belong.

The authorized_keys file should contain public key part of your account key pair. That's no way related to .pub files from %PROGRAMDATA%/ssh.

A comment in the authorized_keys file does not matter at all.

Keys from authorized_keys file are not loaded when the server starts. They are loaded only, when you try to log in.

See also my guides to:


Note that if you are setting up keys for an administrator user, putting the public key to %USERPROFILE%/.ssh/authorized_keys will not work. You must append the public key to %PROGRAMDATA%/ssh/administrators_authorized_keys instead.


And you have to set permission with this script run in powershell admin:

$acl = Get-Acl C:\ProgramData\ssh\administrators_authorized_keys
$acl.SetAccessRuleProtection($true, $false)
$administratorsRule = New-Object system.security.accesscontrol.filesystemaccessrule("Administrators","FullControl","Allow")
$systemRule = New-Object system.security.accesscontrol.filesystemaccessrule("SYSTEM","FullControl","Allow")
$acl | Set-Acl
  • 11
    Note that you also have to set the ACLs correctly. See concurrency.com/blog/may-2019/…. Commented Mar 26, 2020 at 3:15
  • 2
    Kurtis Rader's saying is really crucial!
    – tigertang
    Commented Apr 27, 2020 at 14:03
  • 8
    I can't stress enough how absolutely bonkers it is that changing file permissions is such a verbose operation on Windows
    – korona
    Commented Feb 4, 2021 at 9:12
  • I had everything done but the powershell script... thanks!
    – JCQuintas
    Commented Jul 7, 2021 at 20:52
  • 2
    This is chmod 600 ~/.ssh/authorized_keys on every other operating system... alas this worked, thank you!
    – cswilby
    Commented Oct 8, 2021 at 20:04

I was just struggling with this for approx two hours but what one was only mentioned as sidenote in Martins Article was finally the solution to me:

Setting up SSH public key authentication

Though, with the default Win32-OpenSSH configuration there is an exception set in sshd_config for accounts in Administrators group. For these, the server uses a different location for the authorized keys file: %ALLUSERSPROFILE%\ssh\administrators_authorized_keys (i.e. typically C:\ProgramData\ssh\administrators_authorized_keys).

So as my user is a member of the Administrators group all I had to do is move my ~/.ssh/authorized_keys to %PROGRAMDATA/ssh/administrators_authorized_keys

BTW: I'm running Windows 11 Pro 22H2

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .