Manage Passwords in CLI with Pass and Tomb

Georgijs Radovs
7 min readJul 17, 2022

--

Hello, everyone.
Just wanted to share my experience on how I manage passwords in a CLI environment.

Tools

To setup our environment, we are going to use the following tools:

Pass

Website:

Password management should be simple and follow Unix philosophy. With pass, each password lives inside of a gpg encrypted file whose filename is the title of the website or resource that requires the password. These encrypted files may be organized into meaningful folder hierarchies, copied from computer to computer, and, in general, manipulated using standard command line file management utilities.

Tomb

Website:

Tomb is an 100% free and open source system for file encryption on GNU/Linux, facilitating the backup of secret files. Tomb is written in code that is easy to review and links commonly shared components.

Tomb generates encrypted storage folders to be opened and closed using their associated keyfiles, which are also protected with a password chosen by the user.

A tomb is like a locked folder that can be safely transported and hidden in a filesystem; its keys can be kept separate, for instance keeping the tomb file on your computer harddisk and the key files on a USB stick.

Pass Extensions

pass-otp — to manage OTP-tokens.
pass-tomb — to store passwords in an encrypted container.

Setting Up

Install Packages

Ubuntu:

# apt install pass pass-extension-otp pass-extension-tomb tomb

openSUSE:

# zypper install password-store pass-otp

pass-tomb extension is not available in openSUSE repositories, so we will get it directly from the repository and install it manually:

$ git clone https://github.com/roddhjav/pass-tomb ~/Downloads
$ cd ~/Downloads/pass-tomb && sudo make install

tomb package is also not available in the default openSUSE repositories, so we have two choices:

I use openSUSE Tumbleweed on my laptop and I chose the second option:

$ cd ~/Downloads && wget https://files.dyne.org/tomb/releases/Tomb-2.9.tar.gz
$ tar xvf Tomb-2.9.tar.gz
$ cd Tomb-2.9 && $ sudo make install

After packages have been installed, it is time to configure and initialize the password-store.

Initialization

First, we create GPG keys, which will be used to encrypt password files and tomb files. You can use a single GPG key for both tomb and password-store, for convenience.
Generate keys using gpg2 :

$ gpg2  --generate-key

When GPG asks, you can use Name and Email fields to distinguish, which key is used for what purpose:

gpg2 --list-keys tomb@localhost
pub ed25519 2022-07-17 [SC] [expires: 2024-07-16]
CEA18C257AE7F8EE6BEE1DFAB812D4B2351F850A
uid [ultimate] Tomb Encryption Key <tomb@localhost>
sub cv25519 2022-07-17 [E] [expires: 2024-07-16]
gpg2 --list-keys pass@localhost
pub ed25519 2022-07-17 [SC] [expires: 2024-07-16]
9A5C25FBBC97DA06A72FE53CEBA4150C580DBF49
uid [ultimate] Password Store <pass@localhost>
sub cv25519 2022-07-17 [E] [expires: 2024-07-16]

After GPG keys are ready for use, we will configure pass-tomb extension.

Create a directory where you will store your .pass.tomb and .pass.tomb.key files:

$ mkdir /home/user/definitely_not_passwords

Export environment variables for pass-tomb to be able to find the password-store directory, .pass.tomb and .pass.tomb.key files:

$ export PASSWORD_STORE_DIR=/home/user/.password-store
$ export PASSWORD_STORE_TOMB_FILE=/home/user/definitely_not_passwords/.pass.tomb
$ export PASSWORD_STORE_TOMB_KEY=/home/user/definitely_not_passwords/.pass.tomb.key

Initialize pass-tomb:

pass tomb --no-init --verbose --force tomb@localhost 
. pass Creating a password tomb with the GPG key(s): tomb@localhost
. tomb . Commanded to dig tomb
. tomb (*) Creating a new tomb in /home/user/definitely_not_passwords/.pass.tomb
. tomb . Generating /home/user/definitely_not_passwords/.pass.tomb of 10MiB
. 10+0 records in
. 10+0 records out
. 10485760 bytes (10 MB, 10 MiB) copied, 0.0206397 s, 508 MB/s
. -rw------- 1 user user10M jul 17 16:51 /home/user/definitely_not_passwords/.pass.tomb
. tomb (*) Done digging /home/user/definitely_not_passwords/.pass.tomb
. tomb . Your tomb is not yet ready, you need to forge a key and lock it:
. tomb . tomb forge /home/user/definitely_not_passwords/.pass.tomb.key
. tomb . tomb lock /home/user/definitely_not_passwords/.pass.tomb -k /home/user/definitely_not_passwords/.pass.tomb.key
. tomb . Commanded to forge key /home/user/definitely_not_passwords/.pass.tomb.key with cipher algorithm AES256
. tomb [W] This operation takes time. Keep using this computer on other tasks.
. tomb [W] Once done you will be asked to choose a password for your tomb.
. tomb [W] To make it faster you can move the mouse around.
. tomb [W] If you are on a server, you can use an Entropy Generation Daemon.
. 512+0 records in
. 512+0 records out
. 512 bytes copied, 0.000389054 s, 1.3 MB/s
. tomb (*) Using GnuPG key(s) to encrypt your key: /home/user/definitely_not_passwords/.pass.tomb.key
. tomb . (You can also change it later using 'tomb passwd'.)
. tomb [W] You are going to encrypt a tomb key with 1 recipient(s).
. tomb [W] It is your responsibility to check these fingerprints.
. tomb [W] The fingerprints are:
. tomb [W] CEA18C257AE7F8EE6BEE1DFAB812D4B2351F850A :: Tomb Encryption Key <tomb@localhost>
. tomb . Key is valid.
. tomb . Done forging /home/user/definitely_not_passwords/.pass.tomb.key
. tomb (*) Your key is ready:
. -rw------- 1 user user 971 jul 17 16:51 /home/user/definitely_not_passwords/.pass.tomb.key
. tomb [W] File is not yet a tomb: /home/user/definitely_not_passwords/.pass.tomb
. tomb . Valid tomb file found: /home/user/definitely_not_passwords/.pass.tomb
. tomb . Commanded to lock tomb .pass.tomb
. tomb . Checking if the tomb is empty (we never step on somebody else's bones).
. tomb . Fine, this tomb seems empty.
. tomb . Key is valid.
. tomb . Locking using cipher: aes-xts-plain64
. tomb (*) Locking .pass.tomb with /home/user/definitely_not_passwords/.pass.tomb.key
. tomb . Formatting Luks mapped device.
. tomb . Formatting your Tomb with ext4 filesystem.
. tomb . Done locking .pass using Luks dm-crypt aes-xts-plain64
. tomb (*) Your tomb is ready in /home/user/definitely_not_passwords/.pass.tomb and secured with key /home/user/definitely_not_passwords/.pass.tomb.key
. tomb . Commanded to open tomb /home/user/definitely_not_passwords/.pass.tomb
. tomb . Valid tomb file found: /home/user/pdefinitely_not_passwords/.pass.tomb
. tomb . Key is valid.
. tomb (*) Opening .pass on /home/user/.password-store/
. tomb . This tomb is a valid LUKS encrypted device.
. tomb . Cipher is "aes" mode "xts-plain64" hash "sha512"
. DM-UUID for device tomb..pass-test.eecf947f8a477774194d3cd4d12ebbab026c257ed7f2658714910ee4c2bf1fb9.loop1 was truncated.
. tomb (*) Success unlocking tomb .pass
. tomb . Filesystem detected: ext4
. tomb . Checking filesystem via /dev/loop1
. fsck from util-linux 2.37.4
. .pass: clean, 11/2048 files, 1618/8192 blocks
. tomb (*) Success opening .pass.tomb on /home/user/.password-store/
. pass Setting user permissions on /home/user/.password-store/
(*) Your password tomb has been created and opened in /home/user/.password-store.
. Your tomb is: /home/user/definitely_not_passwords/.pass.tomb
. Your tomb key is: /home/user/definitely_not_passwords/.pass.tomb.key
. You need to initialise the store with 'pass init gpg-id...'.
. When finished, close the password tomb using 'pass close'.

If you would like to initialize using a single GPG key for both tomb and password-store — omit --no-init flag. This way, tomb will initialize password-store automatically.

Initialize password-store:

$ pass init pass@localhost && cd /home/user/.password-store
$ ls -l
total 22
drwxr-xr-x 3 user user 1024 jul 17 20:40 .
drwx------ 34 user user 4096 jul 17 21:13 ..
-rw------- 1 user user 15 jul 17 20:37 .gpg-id
-rw-r--r-- 1 user user 10 jul 17 16:51 .host
-rw-r--r-- 1 user user 11 jul 17 16:51 .last
drwx------ 2 user user 12288 jul 17 16:51 lost+found
-rw-r--r-- 1 user user 12 jul 17 16:51 .tty
-rw-r--r-- 1 user user 5 jul 17 16:51 .uid
$ cat .gpg-id
pass@localhost
$ pass
Password Store
└── lost+found

After this, initialization should be complete.

Configuration

A quote from pass website about data organization in password store:

The password store does not impose any particular schema or type of organization of your data, as it is simply a flat text file, which can contain arbitrary data. Though the most common case is storing a single password per entry, some power users find they would like to store more than just their password inside the password store, and additionally store answers to secret questions, website URLs, and other sensitive information or metadata. Since the password store does not impose a scheme of it’s own, you can choose your own organization. There are many possibilities.

Here is how I structure data in my password store:

$ pass generate personal/finance/crypto/example.com/password
$ pass otp insert personal/finance/crypto/example.com/otp
$ pass
Password Store
├── lost+found
└── personal
├── finance
│ ├── crypto
│ │ ├── example.com
│ │ │ ├── otp
│ │ │ └── password
$ ls -l /home/user/.password-store/personal/finance/crypto/example.com
total 2
-rw------- 1 user user 580 jul 3 19:48 otp.gpg
-rw-r--r-- 1 user user 475 jul 3 19:48 password.gpg

You can configure it in the same manner or try something that suits you better. :)

Now, that everything is initialized and configured, It is recommended to create a shell alias for pass, specifying shell variables we’ve exported earlier, so you don’t have to export them all the time:

$ touch /home/user/.aliases
$ vim /home/user/.aliases
alias pass='PASSWORD_STORE_TOMB_FILE=~/definitely_not_passwords/.pass-test.tomb PASSWORD_STORE_TOMB_KEY=~/definitely_not_passwords/.pass-test.tomb.key PASSWORD_STORE_DIR=~/.password-store'

Add this line to your shell’s rc file, for example, .bashrc:

test -s ~/.aliases && source ~/.aliases || true

Separate .aliases file allows us to have an uncluttered shell rc file and shell aliases defined in a clean way.

After all is done, you should be able to run pass close command, close your password-store and store all your passwords in .pass.tomb file:

$ pass close -v -f 
. pass Closing the password tomb /home/user/definitely_not_passwords/.pass.tomb

[sudo] Enter password for user user to gain superuser privileges


. tomb . Closing tomb [.pass] mounted on /home/user/.password-store
. tomb (*) Tomb [.pass] closed: your bones will rest in peace.
(*) Your password tomb has been closed.
. Your passwords remain present in /home/user/definitely_not_passwords/.pass.tomb.
$ ls ~/.password-store-test
$ pass
Password Store

What is cool is that now, you can store .pass.tomb file with your passwords in git or any other storage solution!
Thanks to tomb and pass-tomb extension, our password store is encrypted in .pass.tomb file and its password-file structure is not exposed to prying eyes.

Password store after pass open:

$ pass
Password Store
├── lost+found
└── personal
├── finance
│ ├── crypto
│ │ ├── example.com
│ │ │ ├── otp
│ │ │ └── password

Password store after pass close:

$ pass
Password Store

That is it!

Don’t forget to run pass open after you reboot your PC. :)

Thank you for your attention and have a nice day!

P.S

If you notice any typos or mistakes — drop a comment and I will fix it. Thank you.

--

--