Skip to main content

Bitwarden-backed SSH agent

Project description

bwssh

Bitwarden-backed SSH agent for Linux. Store your SSH keys in Bitwarden and use them seamlessly with any SSH client.

Features

  • Bitwarden integration: SSH keys stored securely in your Bitwarden vault
  • Standard SSH agent: Works with ssh, git, and any SSH client
  • Systemd integration: Runs as a user service, starts on login
  • Forwarding protection: Blocks remote servers from using your keys
  • Optional polkit prompts: Desktop authorization popups (disabled by default)

Requirements

  • Linux with systemd user services (including WSL2)
  • Python 3.12+
  • Bitwarden CLI (bw) installed and logged in

Installation

uv sync

Bitwarden CLI

Install the Bitwarden CLI (bw) and log in before using bwssh. See https://bitwarden.com/help/cli/ for installation instructions.

bw --version
bw login

Quick start

uv run bwssh install --user-systemd
uv run bwssh start
uv run bwssh unlock
export SSH_AUTH_SOCK=${XDG_RUNTIME_DIR}/bwssh/agent.sock
ssh -T git@github.com

Configuration

Config file: ~/.config/bwssh/config.toml

Quick Setup (Recommended)

The easiest way to configure bwssh is to use the init command:

# First, unlock Bitwarden
export BW_SESSION=$(bw unlock --raw)

# Then run init to auto-discover SSH keys
bwssh config init

This will find all SSH keys in your Bitwarden vault and create a config file.

Manual Setup

If you prefer to configure manually, first find your SSH key IDs:

bw list items | jq -r '.[] | select(.sshKey != null) | "\(.id) \(.name)"'

Then create ~/.config/bwssh/config.toml:

[bitwarden]
bw_path = "/full/path/to/bw"  # Use 'which bw' to find this
item_ids = [
    "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",  # your-key-name
]

Full Config Example

[daemon]
log_level = "INFO"

[bitwarden]
bw_path = "/usr/bin/bw"
mode = "explicit"
item_ids = [
    "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
]

[auth]
# Polkit authorization prompts (default: disabled)
require_polkit = false

# Block forwarded agent requests (recommended)
deny_forwarded_by_default = true

[ssh]
allow_ed25519 = true
allow_ecdsa = true
allow_rsa = true

WSL2 + Windows Bitwarden app mode

If you already use Bitwarden/SSH agent on Windows, you can run bwssh in bridge mode so WSL tools use that agent state.

[bitwarden]
mode = "windows_bridge"
windows_pipe_command = ["npiperelay.exe", "-ei", "-s", "//./pipe/openssh-ssh-agent"]
auto_unlock_poll_seconds = 5

Behavior in this mode:

  • bwssh unlock does not ask for a password in WSL.
  • It reports whether Windows is already unlocked or asks you to unlock in the Windows app.
  • The daemon polls automatically and switches between locked/unlocked when the Windows app state changes.

Environment Variables

  • BWSSH_RUNTIME_DIR: Override socket directory
  • BWSSH_LOG_LEVEL: Override log level
  • BW_SESSION: Bitwarden session key (auto-detected by bwssh unlock)

Security

Default Mode

By default, bwssh allows all local signing requests without prompts. Security comes from:

  • Auto-lock on sleep: Keys are cleared when your laptop sleeps (enabled by default)
  • Forwarded agent blocking: Remote servers can't use your keys
  • Manual lock: Run bwssh lock when stepping away

Polkit Prompts (Optional)

For extra security, enable polkit to show desktop prompts for each signing request:

[auth]
require_polkit = true

This requires installing the polkit policy:

bwssh install --polkit | sudo tee /usr/share/polkit-1/actions/io.github.reidond.bwssh.policy > /dev/null

See docs/ for detailed polkit setup instructions.

CLI Commands

# Daemon control
bwssh start              # Start the agent daemon
bwssh stop               # Stop the agent daemon
bwssh status             # Show daemon status

# Key management
bwssh unlock             # Unlock vault and load keys
bwssh lock               # Lock agent and clear keys
bwssh sync               # Reload keys from Bitwarden
bwssh keys               # List loaded SSH keys

# Configuration
bwssh config init        # Auto-discover SSH keys and create config
bwssh config show        # Show current configuration

# Installation
bwssh install --user-systemd   # Install systemd user service
bwssh install --polkit         # Print polkit policy file

System Tray

bwssh includes an optional system tray icon (bwssh tray) that shows agent status and provides quick lock/unlock controls. Install with the gui extra:

uv tool install bwssh[gui]

Build dependencies

PyGObject must be compiled from source, which requires system development packages.

Fedora / RHEL / CentOS:

sudo dnf install gobject-introspection-devel cairo-gobject-devel python3-devel \
    gtk3-devel libayatana-appindicator-gtk3

Arch / Manjaro:

sudo pacman -S gobject-introspection cairo python gtk3 libayatana-appindicator

openSUSE:

sudo zypper install gobject-introspection-devel cairo-devel python3-devel \
    gtk3-devel typelib-1_0-AyatanaAppIndicator3-0_1

Debian / Ubuntu:

sudo apt install libgirepository1.0-dev libcairo2-dev python3-dev \
    libgtk-3-dev libayatana-appindicator3-1 gir1.2-ayatanaappindicator3-0.1

Alternatively, skip building from source by using system-installed PyGObject:

sudo dnf install python3-gobject gtk3 libayatana-appindicator-gtk3  # Fedora
uv tool install --system-site-packages bwssh[gui]

Documentation

Full documentation lives in docs/ and can be served locally:

cd docs
bun install
bun run dev

Development

uv run ruff check .
uv run ruff format .
uv run mypy src tests
uv run pytest

Project details


Download files

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

Source Distribution

bwssh-0.1.7.tar.gz (46.1 kB view details)

Uploaded Source

Built Distribution

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

bwssh-0.1.7-py3-none-any.whl (61.8 kB view details)

Uploaded Python 3

File details

Details for the file bwssh-0.1.7.tar.gz.

File metadata

  • Download URL: bwssh-0.1.7.tar.gz
  • Upload date:
  • Size: 46.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for bwssh-0.1.7.tar.gz
Algorithm Hash digest
SHA256 6efc9c13dc4d2da6669b4fff4a0a81700e8ae0fe902b4be66e4fcb4335f5cf5a
MD5 6afcc09357fdcafc8940ead983bfa592
BLAKE2b-256 845f7e5c6c1a305586dee795c2dce5e85542f04a374603025325dfaf8573e3cf

See more details on using hashes here.

File details

Details for the file bwssh-0.1.7-py3-none-any.whl.

File metadata

  • Download URL: bwssh-0.1.7-py3-none-any.whl
  • Upload date:
  • Size: 61.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for bwssh-0.1.7-py3-none-any.whl
Algorithm Hash digest
SHA256 aacade99f78fd782698b3ff97dc3581b1c2b377d1e2d917d2d0e7b1b838b218a
MD5 6e4de5397673e78b69c00e024f33a757
BLAKE2b-256 503480b09ad3cdfc5bb6cd7c12f709bff14e2605c4a989a513446f71e043d337

See more details on using hashes here.

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