Yubikey, gpg, ssh and WSL2 - using win-gpg-agent

Last year, we saw how to integrate gpg, ssh and WSL2 environment with smartcard, it was quite messy with alot of moving parts. SPOILERS It still is, although with a bit less moving parts ;)

Indeed, I took time to read rupor’s win-gpg-agent project. He has interesting resources and tools to help easing the integration. This article focuses on how-to quickly setup an integration with the help of rupor’s tools ~Make sure to check out his work~.

Install GnuPG

On windows, you’ll have to install GPG. You can use the method you prefer. I chose to use winget:

winget install GnuPG

⚠ Beware: versions >2.3 of GPG expose their socket in %LOCALAPPDATA%\gnupg instead of %APPDATA%\gnupg. It will have its importance with further configuration.
Execute gpgconf --list-dirs to check folders used by GPG.

You can now configure GPG with your smartcard under windows.

Install and configure win-gpg-agent

From project’s release page. Download the zip and extract it somewhere. You’ll have three exe:

Configure agent-gui.exe

The agent-gui.exe looks for the host’s GPG agent, start it and expose a set of sockets which will be interesting for us.
In order to make it work correctly for our case, it needs to know:

If you are lucky, everything work without configuration, otherwise edit a file called agent-gui.conf in win-gpg-agent. Example:

  homedir: "${APPDATA}\\gnupg"
  socketdir: "${LOCALAPPDATA}\\gnupg" # for version > 2.3
  homedir: "./gnupg"

Setting its gui.homedir will also have as effect to get win-gpg-agent’s socket in a subfolder named gnupg.

You can copy a shortcut of agent-gui.exe to folder in shell:startup (WIN+R then type shell:startup) to get it to start with your system.

If you configured everything correctly, you should see a systray icon corresponding to win-gpg-agent

Also, agent-gui.exe also expose configuration for Windows’s openssh client to work correctly with GPG. You just have to launch the tool for it to work.

Use socat + sorelay to relay WSL2 GPG’s socket to window’s ones

TL;DR: Use socat to relay WSL’s ~/.gnupg/S.gpg-agent and ~/.gnupg/S.gpg-agent.ssh respectively to win-gpg-agent’s <win-gpg-agent-dir>\gnupg\S.gpg-agent and <win-gpg-agent-dir>\gnupg\S.gpg-agent

win-gpg-agent expose equivalent of GPG sockets in AF_UNIX format in <win-gpg-agent-dir>\gnupg. It permit us to use socat and win-gpg-agent’s sorelay.exe like this:

socat UNIX-LISTEN:$HOME/.gnupg/S.gpg-agent,fork EXEC:"/mnt/c/win-gpg-agent/sorelay.exe 'C:/win-gpg-agent/gnupg/S.gpg-agent'",nofork # Considering win-gpg-agent is installed under C:\
socat UNIX-LISTEN:$HOME/.gnupg/S.gpg-agent.ssh,fork EXEC:"/mnt/c/win-gpg-agent/sorelay.exe 'C:/win-gpg-agent/gnupg/S.gpg-agent.ssh'",nofork # Considering win-gpg-agent is installed under C:\

Normally, GPG in WSL2 communicates with host’s GPG and you should be able to access your yubikey under WSL2.


In same fashion than last year article, there is a bash script to automate relay setup in daemon style in this gist. You would have to call the script like that:

win-gpg-agent-relay --wingpgagent-dir "/mnt/c/win-gpg-agent" --wingpgagent-sockets-dir "C:/win-gpg-agent/gnupg" foreground # Use start, stop, status or foreground depending on wether you'd like to control it as a daemon

The content of this post reflects my opinion, current state of knowledge and error can slip through its content.
Knowing so, if you think you found an error or inexact content, you are more than welcome to notify it through comment below ⏬.
Also, if you found the content useful and it helped you, consider leaving a comment too or, better, give me fuel buying me a coffee with the link on the top of the website. 🙏