Skip to main content

Imports and existing KeePass db with REF fields into Bitwarden

Project description

KP2BW - KeePass to Bitwarden Converter

PyPI

Fork of jampe/kp2bw, modernized.

Migrates KeePass databases to Bitwarden via the bw CLI, with advantages over the built-in Bitwarden importer:

  • Encrypted in-memory transfer -- data never hits disk unencrypted (except attachments, which are cleaned up after upload)
  • KeePass REF resolution -- username/password references are resolved: matching credentials merge URLs into one entry; differing ones create new entries
  • Passkey migration -- KeePassXC FIDO2/passkey credentials (KPEX_PASSKEY_*) are converted to Bitwarden fido2Credentials
  • Custom properties & attachments -- imported as Bitwarden custom fields or attachments (values > 10k chars auto-upload as files)
  • Long notes handling -- notes exceeding 10k chars are uploaded as notes.txt attachments
  • Idempotent re-runs that sync changes -- safe to run repeatedly; existing entries are updated in place when their KeePass content changed (notes, credentials, URIs, fields) and never duplicated. Disable with --no-update
  • Nested folders -- KeePass folder hierarchy is recreated in Bitwarden
  • Recycle Bin filtering -- deleted entries are automatically excluded
  • Expiry awareness -- expired entries are marked [EXPIRED] in notes; optionally skip them entirely with --skip-expired
  • Metadata preservation -- KeePass tags, expiry dates, and created/modified timestamps are stored as Bitwarden custom fields
  • Tag filtering -- import only entries matching specific tags
  • Organization & collection support -- upload into a Bitwarden organization with automatic or manual collection assignment
  • Full UTF-8 & cross-platform -- works on Windows, macOS, and Linux

Installation

# install with:
uv tool install kp2bw
kp2bw passwords.kdbx

# or run directly without installing:
uvx kp2bw

or from a GitHub URL:

# install with:
uv tool install git+https://github.com/kjanat/kp2bw
kp2bw passwords.kdbx

# run directly without installing:
uvx --from git+https://github.com/kjanat/kp2bw kp2bw passwords.kdbx

Prerequisites

Install the Bitwarden CLI and log in once before using kp2bw:

# optional: point to a self-hosted instance
bw config server https://your-domain.com/

# log in (only needed once; kp2bw uses `bw unlock` afterwards)
bw login <user>

Usage

kp2bw [-h] [-V] [-k PASSWORD] [-K FILE] [-b PASSWORD] [-o ID]
       [-t TAG [TAG ...]] [-c ID] [--path-to-name | --no-path-to-name]
       [--path-to-name-skip N] [--skip-expired | --no-skip-expired]
       [--include-recycle-bin | --no-include-recycle-bin]
       [--metadata | --no-metadata] [--update | --no-update]
       [--include-oversize-secrets] [-y] [-v] [-d]
       FILE
Flag Description Env var
keepass_file Path to your KeePass 2.x database -
-k, --keepass-password KeePass password (prompted if omitted) KP2BW_KEEPASS_PASSWORD
-K, --keepass-keyfile KeePass key file KP2BW_KEEPASS_KEYFILE
-b, --bitwarden-password Bitwarden password (prompted if omitted) KP2BW_BITWARDEN_PASSWORD
-o, --bitwarden-org Bitwarden Organization ID KP2BW_BITWARDEN_ORG
-c, --bitwarden-collection Collection ID, or auto to derive from top-level folder names KP2BW_BITWARDEN_COLLECTION
-t, --import-tags Only import entries with these tags KP2BW_IMPORT_TAGS (comma-separated)
--path-to-name / --no-path-to-name Prepend folder path to entry names (default: off) KP2BW_PATH_TO_NAME
--path-to-name-skip Skip first N folders in path prefix (default: 1) KP2BW_PATH_TO_NAME_SKIP
--skip-expired Skip entries that have expired in KeePass KP2BW_SKIP_EXPIRED
--include-recycle-bin Include Recycle Bin entries (excluded by default) KP2BW_INCLUDE_RECYCLE_BIN
--metadata / --no-metadata Toggle KeePass metadata as custom fields (default: on) KP2BW_MIGRATE_METADATA
--update / --no-update Update existing entries changed in KeePass (default: on) KP2BW_UPDATE
--include-oversize-secrets Offload over-limit secret fields (hidden OTP secrets, passkey attributes, KeePass-protected fields) to a .txt attachment instead of dropping them (default: off) KP2BW_INCLUDE_OVERSIZE_SECRETS
-y, --yes Skip the Bitwarden CLI setup confirmation prompt KP2BW_YES
-v, --verbose Verbose output KP2BW_VERBOSE
-d, --debug Debug output — includes third-party library logs KP2BW_DEBUG
-V, --version Print the installed kp2bw version and exit -

Configuration precedence is always: CLI flag > environment variable > built-in default.

Troubleshooting

bw not found on PATH

kp2bw shells out to the Bitwarden CLI. If bw isn't installed or isn't on your PATH, kp2bw stops before prompting for any passwords with:

ERROR: Bitwarden CLI ('bw') not found on your PATH. ...

Install the CLI and make sure bw --version runs in the same shell, then retry.

"Invalid master password" on bw unlock

If your password contains special shell characters (?, >, &, etc.), wrap it in double quotes when prompted. See jampe/kp2bw#10 and libkeepass/pykeepass#254 for details.

bw serve startup timeout

kp2bw starts bw serve on a random localhost port. If it times out after 60s:

  • Check that bw is installed and on your PATH
  • Run bw login once if you haven't already
  • Ensure no firewall rules block localhost connections
  • Try bw serve --port 8087 --hostname 127.0.0.1 manually to see if it starts

Items skipped unexpectedly during org import

When importing with --bitwarden-org, items already present in the organization vault are matched by folder + name. If you're importing into a specific collection (--bitwarden-collection), only items already in that collection are matched — items in other collections are created.

Re-running to pick up KeePass changes

Re-running kp2bw against the same database updates matched entries in place when their KeePass content changed (notes, password, username, URIs or custom fields), so you no longer need to purge the vault to push edits. Unchanged entries are left untouched. A re-run also uploads any notes.txt / long-field / file attachment that a previously imported entry was missing, and refreshes one whose contents changed in KeePass even when it keeps the same filename (the stale copy is removed only once the new one has uploaded). Pass --no-update (or KP2BW_UPDATE=0) to keep the old skip-only behavior and preserve manual Bitwarden-side edits.

An attachment failed to upload

Attachment uploads are sent through bw serve, which forwards them to your Bitwarden/Vaultwarden server. A rejected file (for example, an image too large for your plan, or an upload that needs premium/organization storage) now reports the server's actual message and is skipped — it no longer aborts the whole migration, so the rest of your entries still import. Resolve the underlying limit and re-run to upload the remaining files.

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

kp2bw-3.4.1.tar.gz (46.4 kB view details)

Uploaded Source

Built Distribution

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

kp2bw-3.4.1-py3-none-any.whl (51.6 kB view details)

Uploaded Python 3

File details

Details for the file kp2bw-3.4.1.tar.gz.

File metadata

  • Download URL: kp2bw-3.4.1.tar.gz
  • Upload date:
  • Size: 46.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","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 kp2bw-3.4.1.tar.gz
Algorithm Hash digest
SHA256 c173cef6c8641e9320d78c0f62e856fece1d6d08ca0930b7f2da70a40153c72e
MD5 ae0746226657805e8970d9db55a6d20e
BLAKE2b-256 0700089e25f60cb0721e415117afc94e8d298436adf5e59b2188ae6dac0c3110

See more details on using hashes here.

File details

Details for the file kp2bw-3.4.1-py3-none-any.whl.

File metadata

  • Download URL: kp2bw-3.4.1-py3-none-any.whl
  • Upload date:
  • Size: 51.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","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 kp2bw-3.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3b1253249716cdf702d3ef83ca3a3ffdd323ad8c01071ec8f3a3e94206f8639f
MD5 8c1c71922c312ee8029e05b28904e353
BLAKE2b-256 959fec1d3e2747e464b3a83bc2df96196398a0ee9403c4ca7b30bfbaa69dfa61

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