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


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:

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

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 using pass 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

  1. Ensure the library is installed: pip install deep-translator
  2. Copy the code into a file or run it as a one-liner: python3 -c '...'

Backup the Vault Using GitHub

You may ask yourself:

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

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!

../