Skip to content

Instantly share code, notes, and snippets.

@tecandrew
Last active January 21, 2026 08:54
Show Gist options
  • Select an option

  • Save tecandrew/98d1e6e62a79640d40e7a652d2fb2e90 to your computer and use it in GitHub Desktop.

Select an option

Save tecandrew/98d1e6e62a79640d40e7a652d2fb2e90 to your computer and use it in GitHub Desktop.
WSL/WSL2 Integration with 1Password SSH

On Windows Side

Enable 1Password's SSH Agent.

Using Powershell, install npiperelay via the scoop package manager.

Set-ExecutionPolicy RemoteSigned -Scope CurrentUser # Optional: Needed to run a remote script the first time
irm get.scoop.sh | iex  # install scoop
scoop install git
scoop bucket add extras
scoop install npiperelay  # install npiperelay

On WSL Side

sudo apt update
sudo apt install socat

Add the following to your ~/.bashrc file

export SSH_AUTH_SOCK="$HOME/.ssh/agent.sock"
(
  set -eu
  piperelay=(setsid socat "UNIX-LISTEN:$SSH_AUTH_SOCK,fork" "EXEC:npiperelay.exe -ei -s //./pipe/openssh-ssh-agent,nofork")
  if ! pgrep --full --exact --uid=${UID} "${piperelay[*]}" >/dev/null
  then
    rm -f "$SSH_AUTH_SOCK"
    ("${piperelay[@]}" &) >/dev/null
  fi
)

Test 1Password SSH Agent

source ~/.bashrc
ssh -T git@github.com
@Fleshgrinder
Copy link

Fleshgrinder commented Nov 9, 2022

Many thanks for this, the nix ssh is simply more efficient to use with its persistent connections.

The Bash part can be simplified/hardened:

export SSH_AUTH_SOCK="$HOME/.ssh/agent.sock"
(
  set -eu
  piperelay=(setsid socat "UNIX-LISTEN:$SSH_AUTH_SOCK,fork" "EXEC:npiperelay.exe -ei -s //./pipe/openssh-ssh-agent,nofork")
  if ! pgrep "-fxU$UID" "${piperelay[*]}" >/dev/null; then
    rm -f "$SSH_AUTH_SOCK"
    ("${piperelay[@]}" &) >/dev/null
  fi
)

@feamcor
Copy link

feamcor commented Aug 3, 2023

Many thanks for this, the nix ssh is simply more efficient to use with its persistent connections.

The Bash part can be simplified/hardened:

export SSH_AUTH_SOCK="$HOME/.ssh/agent.sock"
(
  set -eu
  piperelay=(setsid socat "UNIX-LISTEN:$SSH_AUTH_SOCK,fork" "EXEC:npiperelay.exe -ei -s //./pipe/openssh-ssh-agent,nofork")
  if ! pgrep "-fxU$UID" "${piperelay[*]}" >/dev/null; then
    rm -f "$SSH_AUTH_SOCK"
    ("${piperelay[@]}" &) >/dev/null
  fi
)

The fact that setsid is in piperelay fails the pgrep.
I fixed by moving the setsid outside.

  export SSH_AUTH_SOCK="$HOME/.ssh/agent.sock"
  (
    set -eu
    piperelay=(socat "UNIX-LISTEN:${SSH_AUTH_SOCK},fork" "EXEC:npiperelay.exe -ei -s //./pipe/openssh-ssh-agent,nofork")
    if ! pgrep --full --exact --uid=${UID} "${piperelay[*]}" >/dev/null
    then
      rm -f "${SSH_AUTH_SOCK}"
      (setsid "${piperelay[@]}" &) >/dev/null
    fi
  )

@tecandrew
Copy link
Author

thanks for these recommendations! updated the gist 👌

@AmazingMrX
Copy link

AmazingMrX commented Jan 21, 2026

I continue to follow this gist into 2026!

A brief justification:

The native 1Password solution, that was meant to replace this method, sidesteps proper agent integration by utilizing WSL's inherent ability to run Windows applications directly. It actually calls upon the Windows SSH client from within WSL. This is fine for SSH alone, but if you use WSL & 1Password for git commit signing (which uses the same system we tap into here) the new approach will fail outright. The npiperelay + socat methods work perfectly in these edge cases, allowing seamless SSH and Git signing with 1Password in WSL. This is especially useful if you use the built-in WSL and Git features in Visual Studio Code. These directly run the IDE from within WSL and do not normally have access to Windows apps and services directly.

A script for Chocolatey:

As a developer, I frequently use the Chocolatey package manager for tool chains and project requirements. I was using Scoop here and here alone, but npiperelay has been available on Chocolatey for some time. Unfortunately, it doesn't work with the original ~/.bashrc script by default. This is due to an issue with how Chocolatey's shims (what is exposed on the PATH) work within WSL. Solving this issue requires special handling from the ~/.bashrc script. We have to find and call upon the actual file instead of the usual shim found in the PATH.

export SSH_AUTH_SOCK="$HOME/.ssh/agent.sock"

# Skip quietly if npiperelay.exe is not available
command -v npiperelay.exe >/dev/null 2>&1 || return 0

(
  set -euo pipefail

  # Capture shim output (ignore nonzero exit code - normal for --shimgen-noop)
  shim_output=$(npiperelay.exe --shimgen-noop 2>&1 || true)

  # Extract the real Windows path from the shim output
  real_win_path=$(echo "$shim_output" | \
                  grep "path to executable:" | \
                  cut -d':' -f2- | \
                  sed 's/^[ \t]*//; s/[ \t\r\n]*$//')

  # Use resolved path if available, otherwise fall back to direct PATH lookup
  if [ -n "$real_win_path" ]; then
    np_cmd=$(wslpath -u "$real_win_path")
  else
    np_cmd="npiperelay.exe"
  fi

  # Set up the relay
  piperelay=(setsid socat UNIX-LISTEN:"$SSH_AUTH_SOCK,fork" \
             EXEC:"$np_cmd -ei -s //./pipe/openssh-ssh-agent",nofork)

  # Start only if no existing relay is using this socket
  if ! pgrep -f -u "${UID}" "socat.*$SSH_AUTH_SOCK" >/dev/null 2>&1; then
    rm -f "$SSH_AUTH_SOCK"
    ("${piperelay[@]}" &) >/dev/null 2>&1
  fi
)

This new version of the ~/.bashrc script works with npiperelay from both Chocolatey & Scoop. Pick whichever package manager you like!

For Chocolatey: choco install npiperelay
For Scoop: scoop install npiperelay

All of the other steps from the OP are the same.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment