Skip to main content

Imports and existing KeePass db with REF fields into Bitwarden

Project description

KP2BW - KeePass to Bitwarden Converter

PyPI

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. Each item is stamped with its KeePass UUID in a KP2BW_ID field, so distinct entries that share a title stay separate and a re-run is matched by identity rather than title.
    Disable updates 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 and expiry date are folded into a single KP2BW_META custom field (YAML), omitted when an entry has neither. Created/modified timestamps are not migrated — Bitwarden manages its own creation/revision dates.
  • 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.

Fork of jampe/kp2bw.

Usage/Installation

# run directly
uvx kp2bw@latest

# install globally with:
uv tool install kp2bw

# update with:
uv tool update kp2bw

kp2bw --version
kp2bw passwords.kdbx

or from a GitHub URL (pull requests display a "🧪 Test this PR" section with convenience commands to run the branch without installing):

# 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>

# ensure you get to a point where you are properly logged in
bw status | jq . # jq optional but makes it easier to read the JSON output
// Example return value:
{
	"serverUrl": "https://bitwarden.example.com",
	"lastSync": "2020-06-16T06:33:51.419Z",
	"userEmail": "user@example.com",
	"userId": "00000000-0000-0000-0000-000000000000",
	"status": "locked",
}

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 KP2BW_KEEPASS_FILE
-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 tags/expiry as a KP2BW_META field (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[^offload] 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.

.env file

kp2bw automatically loads a .env file, searched upward from the current working directory, so you can keep your settings (including the database path via KP2BW_KEEPASS_FILE) out of your shell history.

Copy .env.example to .env and uncomment what you need:

KP2BW_KEEPASS_FILE=passwords.kdbx
KP2BW_BITWARDEN_ORG=00000000-0000-0000-0000-000000000000
KP2BW_SKIP_EXPIRED=1

Then just run kp2bw with no arguments. A real shell environment variable still overrides any value in .env (precedence is unchanged: CLI flag > env var > default), and .env is gitignored so secrets stay local.

Troubleshooting

Every run writes a full DEBUG log to a per-user file even when the console stays quiet, so a failed run leaves a complete record to share. On Windows that is %LOCALAPPDATA%\kp2bw\logs; override the file with KP2BW_LOG_FILE or the directory with KP2BW_LOG_DIR. bw serve errors include the server's actual message, and a slow or dropped request no longer aborts the run — failed entries are counted in the summary and a re-run safely picks up where it left off.

See TROUBLESHOOTING.

[^offload]: Bitwarden has a 10k character limit for text fields.

kp2bw can offload any field exceeding that limit (hidden OTP secrets, passkey attributes, KeePass-protected fields)
to a `.txt` file attachment instead of dropping it, so you don't lose data. This applies to long notes as well as
custom fields.

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.5.0.tar.gz (52.6 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.5.0-py3-none-any.whl (57.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: kp2bw-3.5.0.tar.gz
  • Upload date:
  • Size: 52.6 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.5.0.tar.gz
Algorithm Hash digest
SHA256 7cf3241098fbe67ae982f08801ca6ae3ccf1ea1c5c6c7bc3f6c786b277745c36
MD5 b6589dbdff372a2f4b79fceb39ebc25e
BLAKE2b-256 744f6d6d0103f87861104fdd29eea01ba1500c14669b3303d883f6adb68c7eba

See more details on using hashes here.

File details

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

File metadata

  • Download URL: kp2bw-3.5.0-py3-none-any.whl
  • Upload date:
  • Size: 57.0 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.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ac9a7f1bc5f3b0b0d623550b5409536dac677c60964fafa17ceddb05e0434bac
MD5 1eea2a808db3c6adf4a1bd69af52adfd
BLAKE2b-256 b214f15ae0961146526f89c695cdb5f70e358cfd0eac9900c2da8bd9139b22dc

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