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_SOCKmust 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)
- SSH client connects to the proxy socket and requests identities or a signature
- Proxy forwards the request to the system
ssh-agent - If
ssh-agentreturns keys/signature, proxy passes it through (no delay) - If
ssh-agentreturns empty/failure (DB is locked, keys not loaded):- Proxy connects to KeePassXC via the browser extension protocol
- Sends
get-databasehashwithtriggerUnlockto show the unlock dialog - Polls until the database is unlocked or timeout expires
- KeePassXC pushes SSH keys to
ssh-agenton 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 Redirection
The proxy automatically runs launchctl setenv SSH_AUTH_SOCK ~/.keepassxc/agent.sock on startup. This redirects all new processes to use the proxy socket. The proxy saves and forwards to the original system ssh-agent path, so there is no loop.
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
Reboot to restore the original SSH_AUTH_SOCK, or restore it immediately:
launchctl setenv SSH_AUTH_SOCK "$(cat ~/.keepassxc/ssh-agent.json | python3 -c 'import json,sys; print(json.load(sys.stdin).get("system_agent_path",""))')"
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-agentkeys 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:
triggerUnlockonly 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file keepassxc_ssh_agent-0.3.0-py3-none-any.whl.
File metadata
- Download URL: keepassxc_ssh_agent-0.3.0-py3-none-any.whl
- Upload date:
- Size: 17.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
477b64f7026b312809d6bab87c3d8cf008625198648b3b58a8b4b402b93da409
|
|
| MD5 |
c6e8b152e3bd8dfea08621b6e19e7869
|
|
| BLAKE2b-256 |
bdb25792b9f87ca407af41bdc3e89cdc332665310e79bdbb2896b6e2a780920d
|
Provenance
The following attestation bundles were made for keepassxc_ssh_agent-0.3.0-py3-none-any.whl:
Publisher:
pypi.yml on mietzen/keepassxc-ssh-agent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
keepassxc_ssh_agent-0.3.0-py3-none-any.whl -
Subject digest:
477b64f7026b312809d6bab87c3d8cf008625198648b3b58a8b4b402b93da409 - Sigstore transparency entry: 1096631546
- Sigstore integration time:
-
Permalink:
mietzen/keepassxc-ssh-agent@9566f2dbfbfff5a286ee29ff334de173c4ed007e -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/mietzen
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@9566f2dbfbfff5a286ee29ff334de173c4ed007e -
Trigger Event:
release
-
Statement type: