Skip to main content

SSH IdentityAgent proxy that triggers KeePassXC database unlock via TouchID

Project description

KeePassXC SSH Agent

keepassxc-ssh-agent is an SSH IdentityAgent proxy for macOS that automatically triggers KeePassXC database unlock (via TouchID / Quick Unlock) when an SSH key is needed.

Similar to how Strongbox handles SSH keys, this tool sits between your SSH client and the system ssh-agent. When SSH requests a key that isn't loaded (because the KeePassXC database is locked), the proxy triggers KeePassXC's unlock dialog. After you authenticate with TouchID, KeePassXC pushes the keys to ssh-agent, and the SSH operation continues seamlessly.

Prerequisites

  • macOS (uses Unix sockets and KeePassXC's browser extension socket)
  • Python >= 3.10
  • KeePassXC with:
    • Browser Integration enabled (Settings > Browser Integration > Enable browser integration)
    • SSH Agent Integration enabled (Settings > SSH Agent > Enable SSH Agent integration)
    • SSH keys configured with "Add key to agent when database is opened/unlocked"
  • A running ssh-agent (SSH_AUTH_SOCK must be set)

Usage

usage: keepassxc-ssh-agent [-h] [--socket SOCKET] [--config CONFIG]
                           [--timeout TIMEOUT] [-v]
                           {setup,run,status} ...

SSH IdentityAgent proxy that triggers KeePassXC database unlock via TouchID

positional arguments:
  {setup,run,status}
    setup             Associate with KeePassXC (one-time setup)
    run               Start the SSH agent proxy (default command)
    status            Check connection status with KeePassXC

options:
  -h, --help          show this help message and exit
  --socket SOCKET     Path for the agent Unix socket
                      (default: ~/.keepassxc/agent.sock)
  --config CONFIG     Path to config file
                      (default: ~/.keepassxc/ssh-agent.json)
  --timeout TIMEOUT   Timeout in seconds for unlock prompt (default: 30)
  -v, --verbose       Enable verbose logging

Install

pipx install keepassxc-ssh-agent

How It Works

SSH Client ──► SSH agent protocol ──► keepassxc-ssh-agent (proxy)
                                             │
                                             ├─► SSH agent protocol ──► System ssh-agent
                                             │   (forward requests / replay after unlock)
                                             │
                                             └─► Browser extension protocol ──► KeePassXC
                                                 (trigger unlock when keys missing)
  1. SSH client connects to the proxy socket and requests identities or a signature
  2. Proxy forwards the request to the system ssh-agent
  3. If ssh-agent returns keys/signature, proxy passes it through (no delay)
  4. If ssh-agent returns empty/failure (DB is locked, keys not loaded):
    • Proxy connects to KeePassXC via the browser extension protocol
    • Sends get-databasehash with triggerUnlock to show the unlock dialog
    • Polls until the database is unlocked or timeout expires
    • KeePassXC pushes SSH keys to ssh-agent on unlock
    • Proxy retries the original request and returns the result

Setup

One-Time Setup

Make sure KeePassXC is running with browser integration enabled, then:

keepassxc-ssh-agent setup

This will:

  • Generate encryption keys for the browser protocol
  • Request association with KeePassXC (you'll need to approve it in the KeePassXC window)
  • Save the configuration to ~/.keepassxc/ssh-agent.json
  • Optionally create a LaunchAgent for auto-start

Manual Setup

If you skipped the interactive setup prompts, here are the manual steps:

1. Auto-Start the Agent on Login

Create a LaunchAgent to run keepassxc-ssh-agent on login:

cat << 'EOF' > ~/Library/LaunchAgents/org.keepassxc.ssh-agent.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>org.keepassxc.ssh-agent</string>
  <key>ProgramArguments</key>
  <array>
    <string>/path/to/keepassxc-ssh-agent</string>
    <string>run</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
  <key>KeepAlive</key>
  <true/>
  <key>StandardOutPath</key>
  <string>/tmp/keepassxc-ssh-agent.out.log</string>
  <key>StandardErrorPath</key>
  <string>/tmp/keepassxc-ssh-agent.err.log</string>
</dict>
</plist>
EOF
launchctl load -w ~/Library/LaunchAgents/org.keepassxc.ssh-agent.plist

Replace /path/to/keepassxc-ssh-agent with the actual path (find it with which keepassxc-ssh-agent).

Or start manually:

keepassxc-ssh-agent run

2. SSH_AUTH_SOCK Interception

The proxy automatically intercepts SSH_AUTH_SOCK on startup by renaming the system ssh-agent socket (e.g. /tmp/com.apple.launchd.XXX/Listeners) to a .system backup and placing a symlink from the original path to the proxy socket. All SSH clients then connect to the proxy transparently. The proxy forwards requests to the renamed .system socket.

On shutdown, the proxy restores the original socket. No separate LaunchAgent or SSH config is needed — the run command handles everything.

Uninstall

To completely remove keepassxc-ssh-agent:

1. Stop and remove the LaunchAgent

launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/org.keepassxc.ssh-agent.plist 2>/dev/null
rm -f ~/Library/LaunchAgents/org.keepassxc.ssh-agent.plist

2. Restore SSH_AUTH_SOCK

If the agent was running, it restores the original socket on shutdown automatically. If the system socket is still symlinked (e.g. after a crash), reboot or restore manually:

# Find the original socket path
SYSTEM_AGENT=$(cat ~/.keepassxc/ssh-agent.json | python3 -c 'import json,sys; print(json.load(sys.stdin).get("system_agent_path",""))')
# Remove the symlink and restore the backup
rm -f "$SYSTEM_AGENT"
mv "${SYSTEM_AGENT}.system" "$SYSTEM_AGENT"

3. Remove config and socket

rm -rf ~/.keepassxc

4. Uninstall the package

pipx uninstall keepassxc-ssh-agent

Known Limitations

  • macOS only: Uses KeePassXC's browser extension Unix socket at $TMPDIR/org.keepassxc.KeePassXC.BrowserServer
  • DB unlocked but agent cleared: If the database is already unlocked but ssh-agent keys were manually removed (ssh-add -D), the proxy detects empty keys and triggers "unlock", but KeePassXC reports "already unlocked" without reloading keys. Workaround: lock and re-unlock the database in KeePassXC.
  • Multiple databases: triggerUnlock only works for the currently active database tab in KeePassXC.

Development

# Install with dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run tests with coverage
pytest --cov=keepassxc_ssh_agent

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

keepassxc_ssh_agent-0.4.0-py3-none-any.whl (17.8 kB view details)

Uploaded Python 3

File details

Details for the file keepassxc_ssh_agent-0.4.0-py3-none-any.whl.

File metadata

File hashes

Hashes for keepassxc_ssh_agent-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5d0a271a98979a20e06bc619f5f93d15b1072446e15ad6f715ea198aede46b14
MD5 6b7305c7b7bc6dcffb29fa09c0bae4a9
BLAKE2b-256 c6a9166abc58903d0bc3cb2a4a1a309cd2408ed63cb021fa40684411a82fda78

See more details on using hashes here.

Provenance

The following attestation bundles were made for keepassxc_ssh_agent-0.4.0-py3-none-any.whl:

Publisher: pypi.yml on mietzen/keepassxc-ssh-agent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page