Pass, with friends

pass is a simple way to manage password locally, and with git one can collaborate on a password database with friends. The two technologies; pass and gpg have a lot of resources on-line, but when I went looking to set up a team with pass I found resources in several different places that didn’t match up with practices that made sense. Notably several people were creating key-pairs for each database and sharing the actual key-pairs with collaborators, this seemed insane.

The manual for pass is terse and doesn’t cover the concept of teaming. Where the manual for gpg is comprehensive and you can easily get lost. So we’re going to take a specific pathway through this that makes sense in my own ecosystem, here are the objectives:

  • multiple pass databases (e.g. one per project, or team)
  • individual participants use their own keys)
  • bash aliasing and completion for interaction ease

First, assuming this is your first time with gpg you’ll need to generate yourself a keypair, the archlinux wiki is a pretty good resource if you’re overwhelmed with the gpg manual:

gpg --full-gen-key --expert

Options are preferential, however to guide you further, you should consider using Elliptic Curve Cryptography, particularly Curve25519 if you’re at all concerned about what folks in the community are saying.

  • Choose ECC and ECC
  • Choose Curve 25519
  • Choose key does not expire (unless you’ve got a key management strategy of your own)
  • Name and Email are important if you’re going to use this elsewhere, such as publishing to a keyserver

Now list your keys to examine what is in your keyring, it should be nothing other than the key you’ve just created:

gpg --list-public-keys

If you see more keys and you don’t know why they are there (maybe you are using an AUR helper or something that has pulled keys into your keyring for you), you should clean up with gpg --delete-keys <key>.

Now list your private key to verify it exists:

gpg --list-secret-keys

You should see an associated secret key with your recently created public key. As a final measure, you might want to publish your key for your team to be able to independently pull/corroborate:

gpg --send-keys AABBCCDD

Where AABBCCDD is the last eight of your printed public key. You can use the entire length if you like. Now you’re sorted to use pass on your own. We’ll set up two pass databases with the associated aliases and completion, then we’ll add a collaborator. pass will store your pass databases in ~/.password-store by default, it can use other paths, but we’ll assume you can get this from the man page. Let’s create two project based pass databases:

pass init --path=projecta AABBCCDD

pass init --path=projectb AABBCCDD

You can, alternatively use the email address instead of the public key above. Mainly I wanted you to realize that the hash identifiers are important to be aware of. If you use the hash it will be in the pass database as the hash, an email is likely far easier to read. Now verify these exist by listing your ~/.password-store directory, you can also cat the hidden file .gpg-id to see what keys this pass database is using.

Now set up an alias for each project:

vim ~/.bashrc

alias passa="PASSWORD_STORE_DIR=~/.password-store/projecta PASSWORD_STORE_GIT=~/.password-store/projecta pass"
alias passb="PASSWORD_STORE_DIR=~/.password-store/projectb PASSWORD_STORE_GIT=~/.password-store/projectb pass"

Now set up completion for those aliases:

vim ~/.bash_completion

source /usr/share/bash-completion/completions/pass
	PASSWORD_STORE_DIR=~/.password-store/projecta/ _pass
complete -o filenames -o nospace -F _passa passa
	PASSWORD_STORE_DIR=~/.password-store/projectb/ _pass
complete -o filenames -o nospace -F _passb passb

Now you’re able to interact with each pass database with passa and passb respectively. Now let’s get this database tracked in git:

passa git init

passa git remote add origin ss://[email protected]:port/passa.git

passa git push --set-upstream origin master

Now we’re prepared to collaborate with others, just need to add them. Let’s assume your friend gave you their public key as EEFFGGHHII. We need to pull that public key into our keyring, change it’s trust, and sign it:

gpg --receive-keys EEFFGGHHII

Or alternatively, they may give you a key-file by exporting their key (gpg --armor --export EEFFGGHHII >, if thats the case you can import the via:

gpg --import

Now change the trust level. This is where a lot of guides lead you astray, they will tell you to ultimate trust the key (trust 5), which isn’t the intended trust level for this type of interaction. Ultimate Trust is meant to be bestowed upon keys that are introducers in the Web of trust concept. Instead we need to fully trust this key, then locally sign it:

gpg --edit-key EEFFGGHHII

Here we type trust and select 4 for fully trust. Then save. Now sign the key:

gpg --lsign-key EEFFGGHHII

Now you can add them as a collaborator by re-initializing your pass database. This will batch re-encrypt all entries in your database.


Share some secrets with friends!