BitWarden / KeePass diff
Introduction
The purpose of this project is to assist in keeping Bitwarden and KeePass databases in sync. It will identify records that are different in the two databases. The changes can then be made manually or via bwkp-sync.
Usage
Make sure that you synchronize the Bitwarden vault manually before running, to use latest records.
Run in terminal:
bwkp-diff
Common Workflow
bwkp-diff identify # match records between Bitwarden and KeePass
bwkp-diff -v diff # compare matched records in detail
bwkp-diff clean # delete the local mapping database
Options
Use -v or -d options before a command to turn on Verbose (info) or Debug logging, displaying more details, if needed. This is useful if you are troubleshooting in detail.
Commands
identify command will match the records in Bitwarden and KeePass and store the id pairs in a local SQLite database (bwkpdiff.db in the working directory). These are used to then compare the entries in detail.
This command will output to console any inconsistencies and missing records in either database.
Only matched records will be cached for detailed comparison.
When run without options, identify maps both folders and items (equivalent to --all).
identifyoridentify --all— map folders and itemsidentify --folders— map folders/groups onlyidentify --items— map items/entries only
diff will run detailed items comparison, using the mapping created by identify to match entries in Bitwarden and KeePass.
It is recommended to run diff command with -v option.
The diff command now supports a --direction parameter to control what differences are shown:
--direction all(default): Shows differences in both directions--direction bw: Shows items missing in Bitwarden and differences from KeePass perspective--direction kp: Shows items missing in KeePass and differences from Bitwarden perspective
Examples:
bwkp-diff diff --direction all
bwkp-diff diff --direction bw
bwkp-diff diff --direction kp
clean deletes the local SQLite database (bwkpdiff.db) to remove any sensitive mapping data from the computer.
clear-session removes the cached Bitwarden session key (BW_SESSION) so subsequent commands will require re-authentication.
Gotchas
There are some differences that affect the comparison of entries and fields between KeePassXC and BitWarden.
- Passkeys are handled differently and are not directly comparable. Entries with a tag Passkey in KeePassXC are excluded from comparison.
- BitWarden removes newline characters from custom fields, which may result in many false differences. The
\nare ignored in KeePassXC custom fields during comparison.
Prerequisites
- Bitwarden CLI (bw)
- KeePassXC CLI
- Python
Development
- clone the repository
- run with
uv run main.py [command]
or use the run.cmd script
run -v diff -d bw
Logging
You can configure the logging level by setting the LOG_LEVEL environment variable.
Valid values are debug, info, warning, error, and critical.
This value can be stored in the .env file or environment.
See .env.example for an example .env file.
Environment Configuration
The application can read the variables, like KeePass filename, from an .env file or environment.
-
Copy
.env.exampleto.env:copy .env.example .env -
Edit
.envand set theKEEPASS_FILEvariable to point to your KeePass database:KEEPASS_FILE=C:\\path\\to\\your\\database.kdbx -
Run the test command:
bwkp-diff test
The application will prompt you for the password to unlock the KeePass database.
Bitwarden Session Caching
The application now supports Bitwarden session caching to avoid having to unlock the vault every time you run a command.
How it works
-
When you run a command that requires Bitwarden access, the application will:
- First check if a session key exists in the
BW_SESSIONenvironment variable - If a session exists, it will be used automatically (no validation overhead)
- If no session exists, you'll be prompted for your Bitwarden password
- After successful unlock, the session key will be saved to the
BW_SESSIONenvironment variable
- First check if a session key exists in the
-
On Windows, the session key is persisted across terminal sessions using
setx -
On Unix-like systems, the session key is available for the current terminal session only
Performance Optimization
- No session validation: For maximum speed, we don't validate cached sessions with
bw status - Lazy validation: If a session is expired, errors will be handled during actual API calls
- Minimal overhead: Session caching adds virtually no performance penalty
Benefits
- No repeated unlocking: Once you unlock your Bitwarden vault, subsequent commands won't ask for your password
- Maximum speed: Avoids both unlocking overhead and session validation overhead
- Manual control: You can clear the cached session at any time
- Automatic error handling: Expired sessions are handled gracefully during API calls
Session Commands
- Clear cached session:
bwkp-diff clear-session
Environment Variables
BW_SESSION: Contains the cached Bitwarden session key (managed automatically)
Disabling Session Caching
If you prefer to always enter your password, you can disable session caching by passing use_cached_session=False when creating the Bitwarden client.
Alternative: Environment Variable
Instead of using a .env file, you can also set the environment variable directly:
set KEEPASS_FILE=C:\\path\\to\\your\\database.kdbx
bwkp-diff test
Or on Unix/Mac:
export KEEPASS_FILE=/path/to/your/database.kdbx
bwkp-diff test
References
- https://github.com/jampe/kp2bw
- https://codeberg.org/k3karthic/bitwarden-to-keepass
- https://github.com/bitwarden/clients/blob/7f34abfeadb9620e85c72324f6862c76b88af249/libs/common/src/vault/enums/cipher-type.ts
- https://bitwarden.com/help/cli/
Bitwarden Item Types
Type Value,Description 1,Login – Stores usernames, passwords, and URIs for websites or services. 2,Secure Note – Stores sensitive text notes (e.g., software licenses, recovery codes). 3,Card – Stores credit/debit card information (number, expiry, CVV, etc.). 4,Identity – Stores personal identity information (name, address, passport details, etc.). 5,SSH Key
To-Do
- create a map of KP / BW folders
- create a map of KP / BW entries (id to id)
- compare standard fields (diffentity)
- TOTP
- custom fields
- resolve REF values in fields in KeePass entries
- attachments