Manage Passwords in Linux Ecosystem with Pass Utility

Password based authentications are very common. However storing and securing passwords is an hassle. There are already too many offline and online only services, which does this work for you. Others are more feature-rich and offer lot of other features. If you work in an offline (or air-gap, disconnected from internet, etc) environment, you can use a simple open source utility called pass. It can be used to store each password as a separate file with gpg encryption. It is CLI based, but there are GUI extensions available and has a lot of support in the community.

Also with git, you can choose to sync the encrypted passwords with internal source repos as well, so that you can get all benefits of gitops as well.

Install and Setup Pass

Installing it is as simple as asking your package manager to do it. Official instructions are covered here. In our case, since we are running on RHEL 8, we can use yum install. However for some reason it did not worked on my machine, so I had to download tarball and use make to do the needful:

[cloud_user@96dd25ebf51c pass]$ curl -o password-store.tar.xz https://git.zx2c4.com/password-store/snapshot/password-store-1.7.3.tar.xz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 63416    0 63416    0     0  31503      0 --:--:--  0:00:02 --:--:-- 31503

[cloud_user@96dd25ebf51c pass]$ ls
password-store.tar.xz

[cloud_user@96dd25ebf51c pass]$ tar -xf password-store.tar.xz 

[cloud_user@96dd25ebf51c pass]$ ls
password-store-1.7.3  password-store.tar.xz

[cloud_user@96dd25ebf51c pass]$ cd password-store-1.7.3/

[cloud_user@96dd25ebf51c password-store-1.7.3]$ sudo make install
'man/pass.1' -> '/usr/share/man/man1/pass.1'
'src/completion/pass.bash-completion' -> '/usr/share/bash-completion/completions/pass'
'src/completion/pass.zsh-completion' -> '/usr/share/zsh/site-functions/_pass'
'src/completion/pass.fish-completion' -> '/usr/share/fish/vendor_completions.d/pass.fish'
install: creating directory '/usr/lib/password-store'
install: creating directory '/usr/lib/password-store/extensions'
'src/.pass' -> '/usr/bin/pass'


[cloud_user@96dd25ebf51c password-store-1.7.3]$ pass version
============================================
= pass: the standard unix password manager =
=                                          =
=                  v1.7.3                  =
=                                          =
=             Jason A. Donenfeld           =
=               Jason@zx2c4.com            =
=                                          =
=      http://www.passwordstore.org/       =
============================================

Once its successfully installed, you can run pass version and see output like above.

Once its installed, you need to install gpg key with command gpg2 --gen-key. One of the last steps of the GPG creation process is to set your password. Be sure to use a strong password. This will be your master password to unlock your pass datastore.

Once our secret key is created, we can list it with gpg2 --list-secret-keys:

[cloud_user@96dd25ebf51c password-store-1.7.3]$ gpg2 --list-secret-keys
gpg: checking the trustdb
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2023-04-05
/home/cloud_user/.gnupg/pubring.kbx
-----------------------------------
sec   rsa2048 2021-04-05 [SC] [expires: 2023-04-05]
      6CCF8F4F446016C52C95B7C6DF9371597185A7AD
uid           [ultimate] cloud_user <cloud_user@nonexistentmail.com>
ssb   rsa2048 2021-04-05 [E] [expires: 2023-04-05]

Notice the line starting with sec for secret key. We can see that our key is of rsa-2048 type and has a validity of 2 yrs from now.

With our KeyId, we can initialize password store now:

[cloud_user@96dd25ebf51c pass]$ pass init 6CCF8F4F446016C52C95B7C6DF9371597185A7AD
mkdir: created directory '/home/cloud_user/.password-store/'
Password store initialized for 6CCF8F4F446016C52C95B7C6DF9371597185A7AD

Multiple GPG keys can be specified, for using pass in a team setting, and different folders can have different GPG keys, by using -p.

Generate, Save, Add, Fetch, List, Remove Passwords with Pass

Generate and Save passwords

We can generate new passwords with pass generate command:

# generate password with length of 16 characters
[cloud_user@96dd25ebf51c pass]$ pass generate internet/random-site-1.com 16
mkdir: created directory '/home/cloud_user/.password-store/internet'
The generated password for internet/random-site-1.com is:
=fz~\t<~]zXgHjbM

# generate password without special characters and with length of 16 characters
# if password already exists, it would be overwritten
[cloud_user@96dd25ebf51c pass]$ pass generate --no-symbols internet/random-site-1.com 16
An entry already exists for internet/random-site-1.com. Overwrite it? [y/N] y   
The generated password for internet/random-site-1.com is:
0Z2oOS8GPvKAxo6a


# generate password without special characters, 16-character length and copy to clipboard
# this would need supporting utilities like xclip to be installed
[cloud_user@96dd25ebf51c pass]$ pass generate --no-symbols --clip internet/random-site-2.com 16
/usr/bin/pass: line 160: xclip: command not found
Error: Could not copy data to the clipboard

# generate qrcode as password
[cloud_user@96dd25ebf51c pass]$ pass generate --no-symbols --qrcode business/event-management/cust1.com
mkdir: created directory '/home/cloud_user/.password-store/business'
mkdir: created directory '/home/cloud_user/.password-store/business/event-management'
█████████████████████████████
█████████████████████████████
████ ▄▄▄▄▄ █▀▄█ ▀█ ▄▄▄▄▄ ████
████ █   █ █▀ █ ▀█ █   █ ████
████ █▄▄▄█ █▀▀  ▀█ █▄▄▄█ ████
████▄▄▄▄▄▄▄█▄█ █▄█▄▄▄▄▄▄▄████
████▄▄ ▄ ▀▄▄▄▄▀▀▄▄▀ █▄▀▄▀████
████  ███▀▄ █ ▀▄▄ ▄▀▀▀▀ ▀████
███████▄█▄▄█▀█  ▄█▀█▀▄▀ ▀████
████ ▄▄▄▄▄ █▄▀▄ ▄▀██▀ ▀▄█████
████ █   █ █ ▄▄▄█ ▄▀███▀█████
████ █▄▄▄█ █ █▀▄▄▀▄█▀▄▀██████
████▄▄▄▄▄▄▄█▄▄██▄▄█▄█▄█▄█████
█████████████████████████████
█████████████████████████████

We can store hierarchy of password files as essentially every password is a separate file. So we can store passwords for multiple applications at once and separate them via hierarchy.

Add existing passwords

We can existing passwords with pass insert command:

[cloud_user@96dd25ebf51c pass]$ pass insert business/event-management/cust2.com
Enter password for business/event-management/cust2.com: 
Retype password for business/event-management/cust2.com: 
[cloud_user@96dd25ebf51c pass]$ 

By default, it wont show the password being typed for security reasons. If we need to see the password, that is being entered, we can use --echo:

[cloud_user@96dd25ebf51c pass]$ pass insert --echo business/event-management/cust3.com
Enter password for business/event-management/cust3.com: it echoes!
[cloud_user@96dd25ebf51c pass]$ 

We can use --multiline to enter password of multiple lines and --help to see more options.

List Passwords from store

To list passwords, you need to install tree utility. Once done, you can list all passwords in store with pass command:

[cloud_user@96dd25ebf51c pass]$ pass
Password Store
├── business
│   └── event-management
│       ├── cust1.com
│       ├── cust2.com
│       └── cust3.com
└── internet
    ├── random-site-1.com
    └── random-site-2.com

Fetch Passwords

To fetch a specific password, supply its full path to pass. It will ask you to verify your credentials in a separate prompt. Once provided, it will decrypt and show passsword:

[cloud_user@96dd25ebf51c pass]$ pass internet/random-site-2.com
2bhIqR8PYZv5Pvzj
[cloud_user@96dd25ebf51c pass]$ 

If you do not want to echo on command line, use --copy or -c.

Remove Passwords

To remove a password, supply its full path to pass rm:

# removes passsword
[cloud_user@96dd25ebf51c pass]$ pass rm internet/random-site-2.com
Are you sure you would like to delete internet/random-site-2.com? [y/N] y
removed '/home/cloud_user/.password-store/internet/random-site-2.com.gpg'


# verify its removed
[cloud_user@96dd25ebf51c pass]$ pass
Password Store
├── business
│   └── event-management
│       ├── cust1.com
│       ├── cust2.com
│       └── cust3.com
└── internet
    └── random-site-1.com

Integration with Git

You can sync passwords to an private git repo with Pass as well. If the password store is a git repository, since each manipulation creates a git commit, you can synchronize the password store using pass git push and pass git pull, which call git-push or git-pull on the store. More details on git operations here.

Extensions for Pass

In order to faciliate the large variety of uses users come up with, pass supports extensions. Extensions installed to /usr/lib/password-store/extensions (this is distribution specific path) are always enabled. Extensions installed to ~/.password-store/.extensions/COMMAND.bash are enabled if the PASSWORD_STORE_ENABLE_EXTENSIONS environment variable is true. There are extensions of every kind, GUI extensions, browser extensions, migration specific extensions, etc. You can find more details on official page.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s