bw-migrate is a Linux terminal application for reviewing password-manager
CSV exports and selectively creating login items through the official
Bitwarden CLI. It never edits or deletes the source CSV and never overwrites an
existing vault item.
This is an early, local-only tool. Back up your vault and use a disposable Bitwarden account for the smoke test before trusting it with a migration.
- Linux (the event loop currently uses
inotifyand Unix file permissions) - Rust 1.85 or newer
- Bitwarden CLI
bwavailable onPATH - An unlocked CLI session for vault writes
cargo build --release
export BW_SESSION="$(bw unlock --raw)"
./target/release/bw-migrateReview/import works without Bitwarden access. Keep operations are disabled unless sync, folder listing, and complete item listing all succeed.
The application stores non-password review metadata under
$XDG_STATE_HOME/bw-migrate (normally ~/.local/state/bw-migrate). This
includes usernames, URLs, source paths, decisions, and migration bookkeeping.
The directory is owner-only on Unix. Passwords and notes are reread from the
original CSV only after its SHA-256 fingerprint is verified.
Session caching is disabled by default. To explicitly opt in for one launch:
BW_MIGRATE_CACHE_SESSION=1 ./target/release/bw-migrateThis persists the current BW_SESSION in an owner-only file for a rolling
maximum of 14 days. A session token grants vault access; only enable this on a
trusted, encrypted machine. Press X on the startup screen to remove the
cache, and run bw lock to invalidate the token itself.
- Secret payloads are sent to
bwover stdin, never command-line arguments. - Bitwarden errors are allowlist-sanitized before display.
- Vault reads fail closed so a read error cannot masquerade as an empty vault.
- Every create carries a random
bw-migrate operationcustom field, allowing unambiguous crash recovery without password hashes or heuristic matching. - The source file fingerprint is checked before every reveal or write.
See SECURITY.md for limitations and reporting guidance.
- Create a disposable Bitwarden account and export its session with
bw unlock --raw. - Import a CSV containing only synthetic credentials.
- Create a destination folder and keep one item.
- Confirm its title, URI, username, password, notes, folder, and operation marker in Bitwarden.
- Interrupt the program immediately after another Keep, restart it, and confirm recovery does not create a duplicate.
- Modify the CSV and confirm Reveal and Keep are blocked.
- Disconnect the network and confirm startup fails closed instead of showing an empty vault.
- Delete the disposable account and synthetic export.
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-targets
cargo build --release --locked
cargo deny check
cargo auditCargo.lock is committed because this is an application. crates.io publishing
is intentionally disabled; releases should distribute checksummed Linux
binaries and source archives through the repository hosting service.