pass-import, migrating a password manager into a pass store
A pass extension for importing data from most existing password managers
At a glance
- What is it?
- pass-import is a pass extension that reads an export from 63 password managers and writes the entries into a pass password store, and it ships a companion pimport script for the reverse direction. It is a migration tool, and it only helps once.
- Who is it for?
- pass-import suits a person who has decided to move from a commercial password manager to pass and wants the existing entries, including OTP secrets, carried over rather than retyped. It does not suit someone still deciding, and it does not help with anything that was never in the exported file.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 138 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A one-way door for your passwords
pass import is a password store extension that allows you to import your password database into a password store repository conveniently. The description calls it an extension for importing data from most existing password managers, and it natively supports import from 63 different password managers, with the README noting that more manager support can easily be added.
The scope is deliberate. It is a migration aid, not a sync tool and not a replacement for the manager you are leaving. Its value is that nobody wants to retype two hundred entries by hand, and the formats those managers export are inconsistent enough that writing one importer per manager is a chore worth outsourcing.
Two structural requirements are stated in the README. Passwords are imported into the existing default password store, therefore the password store must have been initialized before with pass init. And by default pass import places entries at the root of the password store and keeps only the main data, meaning password, login, email, URL and group, with the behaviour changeable through the provided options.
The project is GPL-3.0, authored by Alexandre PUJOL, and lives under the passwordstore.org umbrella with the project home page at www.passwordstore.org. The release history shows v3.5 in February 2024, v3.4 in December 2022 and v3.3 in September 2022, and the last push to the repository was on 2026-06-07.
One command per manager and format
The interface is the same everywhere: a manager name, then a file. The README's support table pairs each manager with the formats it understands, where to find the export inside that manager's interface, and the command to run.
A few examples from the table show the spread of formats:
pass import 1password file.csv
pass import aegis file.json
pass import applekeychain file.txt
pass import bitwarden file.json
pass import chrome file.csv
pass import buttercup file.csvThe formats vary because the managers vary. 1Password is supported in csv v4, csv v6, csv v8 and 1pif v4, and the export instructions point at the vendor's own export guide. Bitwarden supports csv and json, and Aegis, andOTP, Blur and Clipperz each export their own format, with Clipperz using html.
There is also a generic csv importer, which is the escape hatch when your manager is not in the list. You tell it which column is which:
pass import csv file.csv --cols 'url,login,,password'The column specification maps positionally to url, login, an empty field, and password, and the fourth slot is left empty because that manager's export has no corresponding field. That single option makes the tool useful against exports nobody has written a dedicated importer for.
pimport exports to eight other managers
The same project also provides a pimport script that allows importing passwords to other password managers. The example the README gives is importing passwords from LastPass to a KeePass database, and it currently supports password export from 8 managers.
That asymmetry is worth understanding. The import direction covers 63 source managers, the export direction covers 8 destinations. The reason is structural rather than accidental: reading a manager's export means parsing a file format the manager produced, and the space of export formats is wide. Writing into a manager means understanding what that manager will accept, and each one has its own model, its own import wizard and its own idea of what a record is.
So the migration story is not symmetric. Moving to pass from almost anywhere is well supported. Moving away from pass to a specific manager is supported for a smaller set, and the practical direction for most people is one-way: get everything into the pass store, where the entries are plain text files in a Git repository, each encrypted with GPG.
The two scripts also share the same packaging. The repository ships import.bash at the top level, which is the extension script pass loads, and the setup file installs both the pass-import and pimport man pages, bash completions and zsh completions alongside it.
Installing it where pass will look for it
The packaging is the part that trips people up, because pass only loads extensions from a specific directory and only when they are enabled.
The setup script computes the extension directory from the platform. On Linux the base is /usr, on macOS it is /usr/local, and the extension lands in the lib/password-store/extensions directory of that base. The man pages, bash completions and zsh site functions are installed under the share directory.
The Makefile gives you the two routes:
make installinstalls system wide with setup.py install against a DESTDIR, and the local target installs for the current user instead:
make localThe local route is the interesting one. With --user, the extension directory is taken from the PASSWORD_STORE_EXTENSIONS_DIR environment variable if it is set, and otherwise from ~/.password-store/.extensions, and the share directory follows XDG_DATA_HOME if it is set, otherwise ~/.local/share. The Makefile echoes a reminder after the local install: set PASSWORD_STORE_ENABLE_EXTENSIONS to 'true' for the extension to be enabled. That last step is not optional, and pass will silently ignore the extension without it.
The build itself is python3 setup.py build, and the docs target generates the man pages with pandoc, which is what makes the share/man/man1/pass-import.1 and pimport.1 files in the tree.
Duplicates, OTP secrets and browserpass
Three compatibility behaviours are called out in the README, and each of them is the kind of detail that decides whether a migration is safe.
Pass import handles duplicates. A password store is a directory of files, and two entries with the same name would collide, so the importer has to have a policy for what happens when a store already contains an entry.
It is compatible with browserpass, the browser extension that lets a password store fill in web forms. Compatibility here matters because the browserpass integration expects a particular structure and a particular field layout in the store, and an importer that wrote a different layout would leave the user unable to use their new store in a browser at all.
And it imports the OTP secret in a way that is compatible with pass-otp, the pass extension for one-time passwords. This is the most valuable of the three, because the OTP secret is exactly the thing that cannot be retyped from memory and is often not recoverable from a backup. A migration that moved the passwords but dropped the one-time secret would leave the user with a password store they cannot log into.
The repository carries the testing and quality tooling to match those claims. There is a tests/ directory with a coveragerc, the Makefile test target runs the suite through green with coverage reporting, the lint target runs prospector at veryhigh strictness over the extension and the shared code, and the security target runs bandit with the .bandit configuration over the package, the tests and the setup script. The project also has GitLab CI configuration, a .gitlab-ci.yml file, alongside the GitHub workflow badges.
What it does not do
There are three limits to keep in view before running an import.
The first is that pass import can only import what the source manager exported. TOTP secrets, secure notes, custom fields, attachments and shared vault items are frequently absent from a CSV export, and no importer can recover what was never in the file. The README's own framing of what is kept by default, password, login, email, URL and group, is a good picture of the realistic ceiling.
The second is the scope of the export direction. pimport supports 8 destination managers. If the manager you want to move to is not among them, the migration out of pass is manual, and a manual export of a few hundred entries is exactly the chore this project exists to avoid.
The third is that the tool is a converter, not a synchroniser. Once entries are in the pass store, they are files in a Git repository encrypted with GPG, and they do not track changes made in the old manager. Treating an import as a one-off event is the correct mental model; treating it as the start of a two-way flow is where people get stuck.
There is a further consideration that no import tool can solve. Moving to a password store means accepting a different security model: entries are files on disk, encrypted per entry with GPG, in a repository you can version and sync, rather than a managed vault with sharing and audit features. The importer does the mechanical work; deciding whether pass is the right home for your passwords is a separate decision.
Editorial conclusion
pass-import suits a person who has decided to move from a commercial password manager to pass and wants the existing entries, including OTP secrets, carried over rather than retyped. It does not suit someone still deciding, and it does not help with anything that was never in the exported file. Before you run it, initialise the store with pass init, export from your current manager in one of the documented formats, and run a single import with the options that control placement, because the default writes to the root of the store and keeps only the main fields.
Frequently asked questions
What does pass-import do and how many password managers does it support?
It is a pass extension that imports a password database into an existing password store, natively supporting import from 63 different password managers, with the README noting that more manager support can easily be added. It also ships pimport, which exports from 8 managers to other password managers.
How do I import from Bitwarden or 1Password into pass?
Export the vault from the manager first, then run the matching command, for example pass import bitwarden file.json or pass import 1password file.csv. The README's support table lists, for each manager, the supported formats, where the export option lives in that manager's interface, and the exact command line.
What do I need to do before running pass import?
The password store must have been initialised first with pass init, because passwords are imported into the existing default password store. You also need to install the extension where pass looks for it and set PASSWORD_STORE_ENABLE_EXTENSIONS to 'true' for the extension to be enabled.
Which fields does pass import keep by default?
By default pass import places entries at the root of the password store and keeps only the main data: password, login, email, URL and group. The behaviour is changeable with the provided options, and for managers that are not natively supported the generic csv importer takes a column mapping such as pass import csv file.csv --cols 'url,login,,password'.
What happens to one-time password secrets during an import?
The README states that pass import imports the OTP secret in a way that is compatible with pass-otp, and that the tool handles duplicates and is compatible with browserpass. What is not exported by the source manager cannot be imported, since the tool works from the exported file.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/roddhjav-pass-import)Was this useful?