A memory-only SSH agent for Windows. Keys live in RAM — never written to disk, registry, or DPAPI.
The built-in Windows OpenSSH agent (ssh-agent service) silently persists every key you add to the Windows registry using DPAPI encryption. Any process running as your user can decrypt those keys without admin privileges, UAC prompts, or any notification. Your "temporary" SSH keys become permanent attack surface.
Ephemeral Agent holds keys in process memory only. When it exits, keys are gone. No registry, no disk, no DPAPI.
- 🔑 Memory-only key storage — keys never touch disk or registry
- 🔌 Drop-in replacement — listens on the standard
\\.\pipe\openssh-ssh-agentpipe - 🖥️ System tray icon — shows key status (grey = empty, green = keys loaded)
- 📋 Right-click menu — clear keys, exit
- 🚀 Login autostart —
--installregisters inHKCU\...\Run - 📦 Single binary — no installer, no dependencies, no runtime
- 🪵 Logging — file log for diagnostics,
--debugfor console output
# Disable the Windows SSH agent service (requires admin)
Set-Service ssh-agent -StartupType Disabled
Stop-Service ssh-agentIf you're using another SSH agent (Bitwarden, 1Password, etc.), disable its agent feature too — only one process can listen on the pipe.
Download ephemeral-agent.exe from Releases and place it somewhere permanent (e.g., C:\Users\you\bin\).
# Run it
.\ephemeral-agent.exe
# Register to start on login
.\ephemeral-agent.exe --install
# Remove autostart
.\ephemeral-agent.exe --uninstall# Load a key (prompts for passphrase if the key has one)
ssh-add ~/.ssh/id_ed25519
# Load all default key files (~/.ssh/id_rsa, id_ed25519, etc.)
ssh-add
# List loaded keys
ssh-add -l
# Remove all keys
ssh-add -DThe system tray icon turns green when keys are loaded.
You can create a simple script to load your keys on login. For passphrase-protected keys, ssh-add will prompt you interactively:
# load-keys.ps1 — run at login via scheduled task or shortcut in shell:startup
ssh-add "$env:USERPROFILE\.ssh\id_ed25519"
ssh-add "$env:USERPROFILE\.ssh\work_key"To run automatically at login, create a scheduled task:
$action = New-ScheduledTaskAction -Execute "powershell.exe" `
-Argument "-NoProfile -File `"$env:USERPROFILE\bin\load-keys.ps1`""
$trigger = New-ScheduledTaskTrigger -AtLogOn -User $env:USERNAME
Register-ScheduledTask -TaskName "Load SSH Keys" -Action $action -Trigger $triggerEphemeral Agent uses Go's golang.org/x/crypto/ssh/agent package, which provides a complete implementation of the SSH agent protocol. Keys are stored in an in-memory keyring (agent.NewKeyring()).
The agent listens on a Windows named pipe at \\.\pipe\openssh-ssh-agent — the same endpoint that ssh.exe, ssh-add.exe, and other OpenSSH tools expect. The pipe's default security descriptor restricts access to the creating user and SYSTEM.
There is no persistence layer. When the process exits, all keys are gone.
# Cross-compile from any OS
GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-H=windowsgui -s -w" -o ephemeral-agent.exe
# The -H=windowsgui flag prevents a console window from appearing on launchOr grab a prebuilt binary from Releases.
Run with --debug to get console output instead of the system tray:
.\ephemeral-agent.exe --debug
# [ephemeral-agent] 2026/03/15 22:02:49 starting ephemeral-agent
# [ephemeral-agent] 2026/03/15 22:02:49 listening on \\.\pipe\openssh-ssh-agent
# [ephemeral-agent] 2026/03/15 22:02:54 connection #1 accepted
# [ephemeral-agent] 2026/03/15 22:02:54 connection #1 ended: EOFIn normal (GUI) mode, logs are written to %TEMP%\ephemeral-agent.log.
| Property | Built-in ssh-agent |
Ephemeral Agent |
|---|---|---|
| Key storage | Registry (DPAPI) | Process memory |
| Persistence | Survives reboot | Until process exits |
| Extraction requires | Any same-user process | SeDebugPrivilege (admin) |
Keys in memory can be extracted by a process with SeDebugPrivilege (typically requires admin). This is the same security boundary as SSH agent forwarding, GPG agent, and similar tools.
The key advantage over the built-in agent is that keys are not persisted to a location readable by any unprivileged same-user process.
If you store SSH keys in Bitwarden, a helper script is included at scripts/load-ssh-keys.ps1. It:
- Prompts for your master password
- Unlocks the vault, syncs, and finds all SSH Key items (Bitwarden type 5) and PEM keys stored in notes
- Pipes each private key to
ssh-add - Immediately locks the vault
# Requires: bw CLI installed and logged in (bw login)
.\scripts\load-ssh-keys.ps1This is entirely optional — Ephemeral Agent works with any key source. The Bitwarden script is just a convenience for users who keep their keys in a password manager.
MIT