Friendship ended with KeePassXC, now UNIX's pass is my best friend


(last time edited: 2021-09-25)

tags: password, storage, security

This week I've been trying to stop using graphical applications and finding better and simpler alternatives with less dependencies. KeePassXC is a great program, very easy to use and graphical intuitive but the standard UNIX password manager achieves the same. It may just take a little to grasp at first but I tell you, you won't be disappointed.

pass saves your passwords in a simple directory tree structure. Each password lives in a .gpg encrypted file and GNU Privacy Guard (GPG) acts like a master password to decrypt all passwords. All passwords will be stored in a newly hidden root directory called .password-store that sits in your home directory. Eventually when you wanna retrieve a password, gpg-agent comes into play. This program runs in the background (daemon) and mantains your GPG decryption in memory for some time so you don't have to re-enter the master password over and over again.

This simple password manager can also be used with Time-based One-time Password (TOTP) by using pass-otp extension.



GNU Privacy Guard (GnuPG or GPG) is a free-software replacement for Symantec's PGP cryptographic software suite. It is compliant with RFC 4880, the IETF standards-track specification of OpenPGP. Modern versions of PGP are interoperable with GnuPG and other OpenPGP-compliant systems.

Install GNU Privacy Guard (GnuPG) in your system. It's usually distributed as gpg or gnupg depending on the distro you're using.

Notice: I use GPG version 1 in this guide. Specifically 1.4.23. You can as well use GPG2 since it comes as a dependency for pass by default.

First generate GPG keys. They will be stored in ~/.gnupg.

$ gpg --gen-key

List all GPG keys stored in your system.

$ gpg --list-secret-keys

Keys will shown in a similar form like this:

pub   2048R/18943772 2021-03-25
uid                 Bernd P. Heinrich <>
sub   2048R/A2831914 2021-03-25

Completely optional. Some applications will look for GPG keys. Make all these applications read your personal GPG key ID by exporting it in a variable. Store it in .bashrc or .mkshrc (depending on the shell you use). You can even export it from .profile or .xprofile. It really depends on what you wanna achieve. This is a nice practice for computers with multiple users.

$ export GPGKEY=18943772

Create a backup of the private key, pass your GPG name in the armor argument with -a.

$ gpg --export-secret-key -a $GPGKEY > ~/gpgpriv.gpg

Create a backup of the public key, pass your GPG ID in the armor argument again.

$ gpg --export -a $GPGKEY > ~/gpgpublic.gpg

If you want to import an already backed up key.

$ gpg --import /path/to/gpgpriv.gpg

When you import a key you need to set the trust level.

$ echo -e "5\ny\n" | gpg --comand-fd 0 --edit-key Bernd P. Heinrich trust


pass is a very simple password store that keeps passwords inside gpg encrypted files inside a simple directory tree residing at ~/.password-store. The pass utility provides a series of commands for manipulating the password store, allowing the user to add, remove, edit, synchronize, generate, and manipulate passwords.

Install pass in your system. The distribution of the program's package name is usually the same as the binary.

Initialize pass storage using the same e-mail you used to create a GPG key.

$ pass init your_email

List all passwords.

$ pass or just $ pass ls

Add a password.

$ pass add myservices/amazon/mylogin


$ pass generate -n myservices/amazon/mylogin

That last command creates an autogenerated password using /udev/random.

Add a password plus more text.

$ pass add --multiline myservices/amazon/mylogin

Remove a password.

$ pass rm myservices/amazon/mylogin

Since pass stores every password as a .gpg file in a directory tree structure, you can also recursively remove the directory.

$ rm -rf ~/.password-store/myservices/amazon

Edit a password and add or remove multiline text. This option will open a text editor. Be sure to have already exported vim as default editor in some rc shell profile.

This command also work as an alternative to add or remove passwords if the .gpg file doesn't exist.

$ EDITOR=vim pass edit myservices/amazon/mylogin

Show a password.

$ pass myservices/amazon/mylogin


$ pass show myservices/amazon/mylogin

And a simple way to edit the .gpg files.

$ pass mv myservices/amazon/mylogin myservices/amazon/my_moms_login

renamed '/home/user/.password-store/myservices/amazon/mylogin.gpg' -> '/home/user/.password-store/myservices/amazon/my_moms_login.gpg'

Copy a password to the Xorg clipboard so you can paste it in graphical applications using Shift + CTRL + V.

Notice: The password will not be printed on terminal, it's not a bug it's a feature!

$ pass show -c myservices/amazon/mylogin

There are multiple ways you can backup your .password-store directory. Using git, rsync, copying recursively, etc.

First install git and initialize a bare repository on a mounted external drive.

$ git init --bare /mnt/some_external_disk/gitpassbackup

Now initialize git in your ~/.password-store directory.

$ pass git init

Add a remote origin to your ~/.password-store directory.

$ pass git remote add origin /mnt/some_external_disk/gitpass

Push the contents.

$ pass git push --set-upstream origin master

There are multiple ways you can backup your passwords. Using git, rsync, rsnapshot, cp, etc. They all have their ups and downs.

Backup using git

pass acts as a git wrapper/pipe.

First create a bare git repository in your external drive.

$ pass git init --bare /path/to/external_drive/backup

Now initialize a git repo inside your ~/.password-store git repo.

$ pass git init

Now add an origin remote to your ~/.password-store git repository, pointing to the backup bare repo.

$ pass git remote add origin /path/to/external_drive/backup

If you made any mistake or changed the mount point of your external drive, you might want to change the origin remote.

$ pass git remote set-url origin /path/to/external_drive/backup

Make it a mirror.

$ git -C /path/to/external_drive/backup config remote.origin.mirror true

Push the passwords and you're done. You've saved your sensible data.

$ pass git push

To retrieve the backup.

$ git clone /path/to/external_drive/backup ~/.password-store

Backup using rsync

With rsync it's just as simple as creating a new directory in a mounted external disk and using rsync to create an incremental backup.

$ mkdir /path/to/backup

$ rsync -av --delete ~/.password-store /path/to/backup

Backup using cp

$ cp -r ~/.password-store /path/to/external_drive/backup


Time-based One-time Password (TOTP) is a computer algorithm that generates a one-time password (OTP) which uses the current time as a source of uniqueness. An extension of the HMAC-based One-time Password algorithm (HOTP), it has been adopted as Internet Engineering Task Force (IETF) standard RFC 6238.

Some programs or web applications make use of this algorithm. Nowadays it's the norm. This type of security sounds dumb in theory, you might ask why make a temporary password of a password? Well, there are extreme some cases that a man-in-the-middle attack can still obtain the one-time-password but it's rather impractical and sounds hollywood-esque. TOTP still is better than SMS-based temporal passwords or old archaic bank token cards. Don't feel bad if you were ever a victim. There are huge companies that still offer stupid security measures because they don't care about the client or taking the time to implement something more secure. Bank token cards are the most stupid idea I ever encountered. Most people working in IT are truly 20 IQ.

I know managing TOTP can be a pain in the ass at first but do yourself a favor, please. I've had clients emotionally on despair consulting me for security on social networking and the solution it's just as simple as turning on any kind of double authentication.

It's very important to keep your system time syncronized using chrony or a similar daemon such as ntpd, otherwise your generated passwords won't work.

Linux Distribution such as Alpine Linux recommend using chrony when # setup-ntp is executed. There are multiple NTP solutions you can choose from, some are lightweight and some aren't.


pass-otp extends the pass utility with the otp command for adding OTP secrets, generating OTP codes, and displaying secret key URIs using the standard otpauth:// scheme.

Install pass-otp or compile it from source if your distro does not offer it.

Add OTP to a previously added password stored. It basically adds a newline of plain text containing the otpauth URI inside the pass .gpg file along the stored plain text password.

$ pass otp append -e myservices/amazon/mylogin

You will be prompted:

Enter otpauth:// URI for myservices/amazon/mylogin:

Enter the following text. Replace SECRET_KEY with the secret key in the following structure. Programs, applications and websites usually give you the secret key in QR codes. Some other give it to you in plain text, in a similar form as DMF8OFAISN82ASDASD2312.

It is not necessary to add any parameter such as algorithm, period or digits. Only the secret and the issuer.


Retrieve an OTP token.

$ pass otp myservices/amazon/mylogin


ZBar is an open source software suite for reading bar codes from various sources, such as video streams, image files and raw intensity sensors. It supports many popular symbologies (types of bar codes) including EAN-13/UPC-A, UPC-E, EAN-8, Code 128, Code 39, Interleaved 2 of 5 and QR Code.

Install ZBar. Usually comes distributed as zbar or zbarcam. It really depends.

If you only got a QR code and no secret key when we were setting up TOTP in some website, you can save that QR image and retrieve the secret key using zbar.

$ zbarimg qrcode.png

Happy hacking!