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"
- Browser Integration enabled (Settings > Browser Integration > Enable browser integration)
Usage
usage: keepassxc-ssh-agent [-h] [--socket SOCKET] [--config CONFIG]
[--timeout TIMEOUT] [-v]
{install,run,status,uninstall} ...
SSH IdentityAgent proxy that triggers KeePassXC database unlock via TouchID
positional arguments:
{install,run,status,uninstall}
install Associate with KeePassXC and install LaunchAgent
run Start the SSH agent proxy (default command)
status Check connection status with KeePassXC
uninstall Remove LaunchAgent and restore SSH_AUTH_SOCK
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
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
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.
Install
Make sure KeePassXC is running and unlocked with browser integration enabled, then:
Homebrew (recommended)
See homebrew homepage on how to setup homebrew.
brew install mietzen/tap/keepassxc-ssh-agent
keepassxc-ssh-agent install --register-only
brew services start keepassxc-ssh-agent
This will:
- Install
keepassxc-ssh-agentand its dependencies - Register with KeePassXC (you'll need to approve the association in the unlocked KeePassXC window)
- Start the background service via Homebrew (auto-starts on login)
pipx - Automatic Install
See pipx installation guide on how to setup pipx.
pipx install keepassxc-ssh-agent
keepassxc-ssh-agent install -y
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 agent configuration to
~/.keepassxc/ssh-agent.json - Save the browser API credentials to
~/.keepassxc/browser-api.json(shared withkeepassxc-cliif installed) - Create a LaunchAgent for auto-start on login
The -y flag auto-accepts all prompts. Without it, you'll be asked interactively whether to create the LaunchAgent.
pipx - Manual Install
If you want more control over the installation, you can split it into steps:
1. Install the package
pipx install keepassxc-ssh-agent
2. Register with KeePassXC
Register with KeePassXC without creating a LaunchAgent:
keepassxc-ssh-agent install --register-only
You'll need to approve the association in the KeePassXC window when prompted.
3. Create a LaunchAgent (optional)
To auto-start the agent on login, create a LaunchAgent plist:
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 bootstrap gui/$(id -u) ~/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 without a LaunchAgent:
keepassxc-ssh-agent run
Uninstall
Homebrew
brew services stop keepassxc-ssh-agent
brew uninstall keepassxc-ssh-agent
rm -rf ~/.keepassxc # Remove config (optional)
pipx
keepassxc-ssh-agent uninstall -y
pipx uninstall keepassxc-ssh-agent
This stops and removes the LaunchAgent, restores the original SSH_AUTH_SOCK socket, and removes the config directory (~/.keepassxc/). Without -y, you'll be asked before deleting the config directory.
Manual Uninstall
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-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
This package depends on keepassxc-browser-api, which handles the KeePassXC browser extension protocol. The browser API credentials are stored in ~/.keepassxc/browser-api.json and are shared with keepassxc-cli if installed.
# 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 Distribution
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-1.3.0.tar.gz.
File metadata
- Download URL: keepassxc_ssh_agent-1.3.0.tar.gz
- Upload date:
- Size: 4.5 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
283e1575109f159cf7237154ce305c99bac68548b68750a0332a4056b8ec688e
|
|
| MD5 |
58de02f8970e2d2e3a1d143a9be39df2
|
|
| BLAKE2b-256 |
b728cfb014defef88dba85c5554517a2d4d84e42c0a17a9e77aca1ee866519a8
|
Provenance
The following attestation bundles were made for keepassxc_ssh_agent-1.3.0.tar.gz:
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-1.3.0.tar.gz -
Subject digest:
283e1575109f159cf7237154ce305c99bac68548b68750a0332a4056b8ec688e - Sigstore transparency entry: 1293689383
- Sigstore integration time:
-
Permalink:
mietzen/keepassxc-ssh-agent@babcecece5e829aa11a35c22b3c719928a116c05 -
Branch / Tag:
refs/tags/v1.3.0 - Owner: https://github.com/mietzen
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@babcecece5e829aa11a35c22b3c719928a116c05 -
Trigger Event:
release
-
Statement type:
File details
Details for the file keepassxc_ssh_agent-1.3.0-py3-none-any.whl.
File metadata
- Download URL: keepassxc_ssh_agent-1.3.0-py3-none-any.whl
- Upload date:
- Size: 15.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
55d453ec3b0f50bcce56d269aa0e481fd08f1e1467313c6f8778d97153d0eb27
|
|
| MD5 |
8fa4cd2eb6d5b7068b1f322e60b237b7
|
|
| BLAKE2b-256 |
6dd97f4514d1729b2f527fee29e4c990e566d738351174abb4965a2efc30cc7f
|
Provenance
The following attestation bundles were made for keepassxc_ssh_agent-1.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-1.3.0-py3-none-any.whl -
Subject digest:
55d453ec3b0f50bcce56d269aa0e481fd08f1e1467313c6f8778d97153d0eb27 - Sigstore transparency entry: 1293689386
- Sigstore integration time:
-
Permalink:
mietzen/keepassxc-ssh-agent@babcecece5e829aa11a35c22b3c719928a116c05 -
Branch / Tag:
refs/tags/v1.3.0 - Owner: https://github.com/mietzen
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@babcecece5e829aa11a35c22b3c719928a116c05 -
Trigger Event:
release
-
Statement type: