Pass the Standard Unix Password Manager
Introduction
Pass is a classic password manager. It doesn’t uses a big one data base for saving passwords. It saves each password in an encrypted file using GPG key.
Why Choosing Pass
- Managed using the terminal by executing short commands.
- It doesn’t depends on any third-party vault provider.
- Fully data control - The passwords hosted in your computer and encrypted, and also encrypted in a private GitHub repository.
- Easy to backup using backup tools. Thanks to the simple file system structure.
- Accessible securely from a browser extension that doesn’t belong to a public vault provider.
- Secured access from the mobile.
Folder Structure
~/.password-store/
├── .gpg-id
├── email/
│ ├── gmail.gpg
│ └── outlook.gpg
├── work/
│ ├── slack.gpg
│ └── github-token.gpg
└── social/
├── facebook.gpg
└── instagram.gpg
~/password-store - By default, This is the home of the pass service.
Every password is an isolated txt file which encrypted using the GPG key and ends in the format .gpg .
~/.gpg-id - This is the identifier of the GPG key. Pass reads this file in order to know what key to use in order to
Install Pass in Linux
Requirements:
- [[GPG Key]]
I personally use Fedora in my workspace. But you can also install it on Ubuntu or any other distribution you like.
Ubuntu apt command:
sudo apt update
sudo apt install pass -y
Install in Fedora, directly in the file system
rpm-ostree install pass
Reboot your computer (In Fedora)
systemctl reboot
Find your gpg identifier
gpg --list-secret-keys --keyid-format=long
Initialize pass using the GPG key
`pass init <GPG-Key-identifier>`
The Output
pass init <gpg key identider>
mkdir: created directory '/var/home/username/.password-store/'
Password store initialized for <gpg key identider>
.password-store - Saved in home directory and backup the passwords.
Basic Commands
Create only password without email, Example of GitHub account
pass insert social/github
Create password including email, Example of GitHub account
pass insert -m social/github
View the github password. Note: It will prompt a window that requires filling your GPG passphrase.
pass social/github
Generate strong password, Wether you created a new account or reset your current one(20 lengts)
pass generate social/github 20
Copy your password, This command copies only password in the top line and ignores the email
pass -c social/github
Delete password by deleting the entire folder
pass rm -r social/
Move folder or changing folder name
pass mv social/github work/github
View the tree of your folders and passwords
pass
Output example:
Password Store
└── social
└── github
Search password by name, GitHub account for the example
pass search social/gitub
Edit pass credentials or any note:
pass edit social/github
pass git add .
pass git commit -m "edited github credentials"
pass git push
Migrate Passwords From Bitwarden
Export Bitwarden from the Browser
- Login to Bitwarden via web. Exporting vault supported only via web.
- Settings->Export->Choose
jsonformat. - Type your master password and download the json file.
Install Pass Migration Tool In Fedora
Note: You can also do it in Ubuntu dist using apt package manager.
Enter your toolbox container
toolbox enter <toolbox container>
Install the dependencies
sudo dnf install -y git pass python3-pip python3-gobject-base
Install the migration tool pass-import using pip package manager
pip install pass-import
Open and copy the following Python script, Paste in the terminal and execute it:
[!code]- script.py
python3 -c ' import json, subprocess, os cards_count = 0 notes_count = 0 logins_count = 0 with open("bitwarden_export.json", mode="r", encoding="utf-8") as f: data = json.load(f) for item in data.get("items", []): name = item.get("name", "").strip() or "unnamed_item" notes = item.get("notes", "") or "" # Sanitize name for file system compatibility name = name.replace(" ", "_").replace("/", "-") # Strict validation based on internal dictionary structures # 1. Check if it is a real Credit Card if "card" in item and item["card"]: card = item["card"] card_num = card.get("number", "") or "N/A" card_name = card.get("cardholderName", "") or "" month = card.get("expMonth", "") or "" year = card.get("expYear", "") or "" cvv = card.get("code", "") or "" content = f"{card_num}\nholder: {card_name}\nexpiration: {month}/{year}\ncvv: {cvv}" if notes: content += f"\nnotes: {notes}" name = f"Cards/{name}" cards_count += 1 # 2. Check if it is a Login elif "login" in item and item["login"]: login = item["login"] password = login.get("password", "") or "" email = login.get("username", "") or "" totp = login.get("totp", "") or "" content = f"{password}\nemail: {email}" if totp: content += f"\ntotp: {totp}" if notes: content += f"\nnotes: {notes}" logins_count += 1 # 3. Everything else goes to Secure Notes (including custom note types) else: content = f"{notes}" if notes else "Empty Note" name = f"Notes/{name}" notes_count += 1 # Create directory structure and encrypt via GPG subprocess.run(["mkdir", "-p", f"/var/home/naory/.password-store/{name}".rsplit("/", 1)[0]]) proc = subprocess.Popen(["gpg", "--batch", "--yes", "-e", "-r", "03DE1CBFD01A929619B00031D3CFDBBCDBF6B350", "-o", f"/var/home/naory/.password-store/{name}.gpg"], stdin=subprocess.PIPE) proc.communicate(input=content.encode("utf-8")) print(f"\n[+] Smart Migration completed successfully!") print(f" - Logins processed: {logins_count}") print(f" - Credit Cards processed: {cards_count}") print(f" - Secure Notes & Keys processed: {notes_count}\n") '
Warning: Delete your csv file once you imported it into pass. It includes your whole vault data!
Translate Password & Folders From Random Language To English
At this example I took my native language which is Hebrew for replacing it by English language. I did it because English is more suitable for using pass in the terminal.
You can replace it by any language you need.
When you import your entire vault, You can find out that some of your accounts are written in another language which it makes it harder to work with and read it through the terminal.
We are going to use a translate tool from the python package manager which based on Google Translate and using the official command pass mv
Create or use your current toolbox container to install deep-translator
This tool scans the entire ~/.password-store folder and translate all the files and folders without corrupting the encrypted files.
toolbox enter <your_existing_toolbox_container>
pip install depp-translator
Copy and execute the following script
[!info]- Python Script: Translate Passwords from Hebrew to English This script scans your
~/.password-store, detects Hebrew file/folder names, translates them to English via Google Translate, and safely renames them usingpass mv.import os, subprocess, re from deep_translator import GoogleTranslator # Using the library standard for Hebrew: "iw" translator = GoogleTranslator(source="iw", target="en") password_store = os.path.expanduser("~/.password-store") def has_hebrew(text): return bool(re.search("[\u0590-\u05fe]", text)) def clean_name(text): text = text.lower().replace(" ", "_") return re.sub(r"[^a-z0-9._-]", "", text) for root, dirs, files in os.walk(password_store): for file in files: if file.endswith(".gpg"): rel_dir = os.path.relpath(root, password_store) pass_name = file[:-4] old_path = pass_name if rel_dir == "." else f"{rel_dir}/{pass_name}" if has_hebrew(old_path): parts = old_path.split("/") new_parts = [] for part in parts: if has_hebrew(part): translated = translator.translate(part) new_parts.append(clean_name(translated)) else: new_parts.append(part) new_path = "/".join(new_parts) print(f"Translating: {old_path} -> {new_path}") subprocess.run(["pass", "mv", old_path, new_path])
[!tip] How to Run
- Ensure the library is installed:
pip install deep-translator- Copy the code into a file or run it as a one-liner:
python3 -c '...'
Backup the Vault Using GitHub
You may ask yourself:
- “Doesn’t it risky to store credentials in a private GitHub repository?”.
- “What if the hacker has the access to my GitHub account?”
Well, Absolutely not risky. Because all the files that we’re pushing into the remote GitHub repository are encrypted by the GPG key. The hacker should get your passphrase to decrypt it the GPG files. If he succeeds to hack your GitHub Repository - He will see a Gibberish files. Good luck :)
Where is your passphrase stored?
In your mind. This is the only password you should remember to decrypt any GPG password file you need.
Getting Started
- Create a private GitHub repository.
- Don’t create any
.gitignore,READMEwhile creating the repository. - Copy the ssh link of your repository.
Initialize and Connect
pass git init
pass git remote add origin <your github repo url>
Create your First Commit
cd ~/.password-store
git branch -M main
Force Pushing The First Change
git push -u origin main --force
How Do We Proceed From Here?
You shouldn’t run the git commit anymore. Every change you do, The Pass does the commit automatically. All you need to do is just pushing your changes by using the command pass git push
Conclusion
Well, You see how easy and secured is to have your own data and not trusting any third-party vendor to host one of the most sensitive data. I hope you enjoy the guide, It would be great if you leave a feedback to make my guides better.
Cheers!