Multiple shared password stores with Git and pass

This article contains ideas and suggestions for a more advanced use of pass; it’s intended for people who already know its basic usage.

Before all, why do I use a trivial command line tool instead of one of the many fancy password managers available?

Because I believe critical things need to be kept simple.

They need to be open source and have proven themselves by being maintained, audited, and used by many.

Even what you think would be a serious security company inadvertently exposed a backdoor on their users’ machines allowing remote code execution and the theft of their passwords (← I really recommend the reading of this story).

pass is one bash script relying on GPG. Both tools are open and have been used extensively for a while.

There are some GUIs for pass, some browser extensions, mobile apps, etc. but choose them carefully: the more we add, the larger the attack surface becomes.

I use Termux on Android, which provides pass in its packages. It doesn't autofill credentials, but apps and websites are good at remembering who you are these days, so I don't need to log in often.

Retrieve a password

First, a little tweak for the retrieval of a password.

The default command — pass -c <password-name> — outputs the password in the clipboard and clears it after 45 seconds.

However, I have a clipboard manager that keeps everything I put in the clipboard.

To prevent passwords from being recorded, I wrote a command that outputs them in the X selection instead of the clipboard. To paste them, I click the middle mouse button, instead of using Ctrl-V.

To do that, add the following in your .zshrc (you might have to make some modifications if you're using a different shell):

Here it is in action:

Set up more than one password store

It’s possible to have two completely separated password stores by creating a new command for the second one. The new command, passpro for instance, will use a different directory:

Having two different pass commands is my preference, but there are other ways to have multiple stores. For instance, you could make use of .gitignore or git submodules to have the second store inside the first one.

Share a password store

We can share a password store with many people, while still being able to fine tune who has access to what.

  • We create a subfolder for each team, for instance a devs subfolder and a support subfolder:
├── devs
│ ├── databasePassword
│ ├── serverSshKey
│ └── stackCredentials
└── support
├── supportPlatformPassword
└── supportEmailPassword
  • Inside each, we put a .gpg-id file listing the PGP key UIDs of the persons having access to the content of this subfolder:
├── devs ┌───────────────────────────┐
│ ├── .gpg-id → │ Alice <> │
│ │ │ Bob <> │
│ │ └───────────────────────────┘
│ ├── databasePassword \
│ ├── serverSshKey > Each file is encrypted
│ └── stackCredentials / for Alice and Bob
└── support ┌───────────────────────────┐
├── .gpg-id → │ Alice <> │
│ │ Carl <> │
│ │ David <> │
│ └───────────────────────────┘
├── supportPlatformPassword \ Each file is encrypted for
└── supportEmailPassword / Alice, Carl and David

And that’s basically it.

There are a few other things to help us:

  • In the root directory, a .public-keys folder contains the public PGP keys of all the persons having access to the store. That allows the creation of new passwords that will be decryptable by the persons/teams we want.
  • The .gpg-id file in the root directory lists who has access to the secrets in this directory — and any subfolder which doesn't have its own .gpg-id. We don't use it in this example.
  • Finally, the bash script is used to display detailed information about the password store, and to reencrypt it when a new user is given access to the store. Indeed, when a new user is added, every passwords he will have access to needs to be reencrypted for his public key. This process is explain later in this article.

So here’s our complete, shared and segmented, professional password store:

├── .public-keys
│ ├── alice.asc
│ ├── bob.asc
│ ├── carl.asc
│ └── david.asc
├── devs ┌───────────────────────────┐
│ ├── .gpg-id → │ Alice <> │
│ │ │ Bob <> │
│ │ └───────────────────────────┘
│ ├── databasePassword
│ ├── serverSshKey
│ └── stackCredentials
├── support ┌───────────────────────────┐
│ ├── .gpg-id → │ Alice <> │
│ │ │ Carl <> │
│ │ │ David <> │
│ │ └───────────────────────────┘
│ ├── supportPlatformPassword
│ └── supportEmailPassword
├── .gpg-id

The content of can be found here.

Now, let’s see how to use the password store.

Add a new password to the shared store

Now that we have the structure of our shared store, let’s create a password.

  • First, we import the all public keys to our keyring:
gpg --import ~/.password-store-pro/.public-keys/*.asc
  • And we trust them — the following needs to be done for each keys:
gpg --edit-key "<key-uid>"
gpg> trust
Your decision? 5
gpg> quit
  • Optionally, we create a new Git branch. As the password store is a Git repository, we can run Git commands on this repository with pass git, for instance:
passpro git checkout -b new-password
  • Choose in which subfolder to put the new password, and generate it:
passpro generate -n devs/cloudPlatformCredentials 20
  • Push the branch and create a pull request.

Give access to the password store to a new user

As stated before, when a new user is added, every passwords he will have access to needs to be reencrypted for his public key.

  • First, we add the user’s public key to the .public-keys directory.
  • Then, we import it to our keyring:
gpg --import .public-keys/*.asc
  • We find its uid:
gpg --list-keys

For instance, the uid can be: Elie <>

  • We trust the public key:
gpg --edit-key "Elie <>"
gpg> trust
Your decision? 5
gpg> quit
  • We add the key’s uid in the .gpg-id file of each subfolder the new user needs to have access to; for instance, let’s say that the new user is a developer, we add the key’s uid in devs/.gpg-id:
Alice <>
Bob <>
Elie <>
  • We now reencrypt all passwords and secrets for the new user:
./ devs

This will list the persons for whom the devs subfolder will be encrypted, and ask you to confirm:

Password store root directory:
1 subfolders will be encrypted.‘devs’ will be encrypted for:
Alice <>
Bob <>
Elie <>
Proceed? [y/N]

./ can also be run without any arguments, to reencrypt the whole store. However, remember that you need access to a password in order to be able to encrypt it for a new user, as you need to decrypt it first.

Decrypting passwords stays as easy than it is with a personal password store. Note that Windows users who only need read access to the passwords can install Gpg4win — instead of a non-official version of Pass.

I hope you enjoyed this article, have fun with Pass!




Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

What is a Honeypot?

Ghost NFT Marketplace will launch soon!

{UPDATE} Peg Solitaire Hack Free Resources Generator

That’s The Ticket TryHackMe walkthrough

Musketeer: Weekly Updates #3

Solved: How to Connect Wireless Printer to Laptop Windows 10

GDPR The Basic Facts — Basis of processing

{UPDATE} Gjett Karikatur - Quiz Spill Hack Free Resources Generator

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store


More from Medium

Encrypting passwords (via Node and Bcrypt)

ARCPG Devlog — Day 7

Lambda Layers In NET Core

Premiere Pro and Media Encoder Integration | Adobe Bridge Tutorial