Managing passwords in teams with Gopass

No Comments

In development teams often a huge number of secret values needs to be shared. The way they are shared is critical for security as leaked secrets are easy targets for hackers. Individuals should use password managers and generated passwords – but also teams should. Gopass is a simple, robust and easy-to-learn answer. Gopass UI offers a fancy user interface on top.

Password managers for teams

Databases, cloud providers, platforms and SaaS providers are only a few cases where credentials need to be shared together in software development teams. And exactly as for personal use, these credentials need to be complex enough and stored securely. It should not be the case that secrets are sent via messengers or email or are kept directly in source code. So it’s recommended to generate secrets and have as little manual interaction with them as possible to treat them safely.

This is where password managers for teams come into play. The idea is that each team member can be technically identified and has access to the secrets and credentials. Where there is something like a public key, there is also a private key for decrypting and signing data. Having a public and private key pair allows team members to encrypt and decrypt secrets for the fixed set of identities within the team. It is of course possible to revoke access from an identity again. Let’s have a look at how the two password managers Pass and Gopass do this and what they offer.

Introducing Pass and Gopass

First of all, what is Pass? Pass states to be “the standard unix password manager” following the Unix philosophy. It is a simple command line tool to encrypt and decrypt passwords using GPG. In addition, it offers a subset of Git functionality, so that the password store can be versioned, backed up and even shared. It is also possible to synchronise the password store directory with cloud services by directly synchronising the password stores directory. Pass provides basic password manager capabilities for command line affine Linux and MacOS users. It is even possible to use it in teams by using Git or synchronisation mechanisms, as described.

user@computer ~ $ pass
Password Store
├── Business
│   ├──
│   ├──
│   └──
├── Private
│   ├──
│   └──
└── Finance
    ├── bank-account
    ├── mobile-phone-provider
    └── not-so-smart-home

Gopass states to be “the slightly more awesome standard unix password manager for teams”. It is written in Go to target cross-platform compatibility and focuses on being a feature-rich password manager for teams. This is useful because different operating systems are definitely a thing in software development and sysadmin teams. Gopass is 100% API-compatible with Pass because it also uses GPG encryption and stores data in the same way. They both maintain directory structures containing encrypted files with clear text filenames. Due to the fact that a secret is just a file, it can be identified using the directory path (e.g. /my-store/some-database/production/password). On top of that, Gopass offers a closer integration with Git. Synchronising your password stores in Gopass means pushing and pulling all remote Git repositories. Adding or editing secrets will result in a push of affected files automatically. Synchronisation with Git, be it local or also remote, can be disabled. It may not be required if the team decides to synchronise the directory structure via cloud services like Google Drive, Dropbox or similar.

Gopass teaser

What makes Gopass outstanding for teams is the fact that it knows about recipients. Each member of a team is represented as a recipient in the teams password store. To onboard new members, a member just needs to register the new member’s public key. Recipients (and preferably only them) need access to the remote Git repository which is hosting the store. When a new recipient is added, all secrets need to be decrypted and encrypted again in a way that the new recipient is also included. Adding a new recipient to the store means that all previous recipients are going go trust the new member’s GPG key. Having this mechanism at hand, it is also possible to revoke access from recipients again. This is convenient for cases where people leave the team, lose their hardware or are affected by their key-pair being hijacked.

Installing and setting up Gopass

The dependencies for Gopass are GPG, Git and a previously generated GPG keypair. Check the dependencies for your environment using these “Pre-Installation Steps”. To install Gopass itself, using go get is recommended if you have Go available in your PATH. Otherwise, have a look at the “Install” section. Major Linux package managers and Homebrew for MacOS have it available, too. For Debian and Ubuntu please download and install the .deb package yourself because the official Debian repositories contain another package named “gopass”. Of course there are also auto completions for bash, zshell and fish available.

It is important for the installation that Git and GPG are compatible. Test this before by initialising a repository, adding something and attempting to do a signed commit (indicated by the -S flag):

mkdir some-dir
cd some-dir
git init
touch foo
git add foo
git commit -S -m "test"

Does that work fine already? Then jump to the next section. Otherwise you should look at the following points for troubleshooting:

  • Does GPG work? Test it by executing echo "test" | gpg ---clearsign
  • Problems with GPG and TTY? Add GPG_TTY=$(tty) && export GPG_TTY to the config of your shell.

Learning the Gopass basics

On first launch it is handy to run the onboarding wizard by running gopass. It guides the user through their first store initialisation, whether you would like to create a local store, team store or join an existing team store. The local one is fine for the start. After doing so, a first secret can be inserted using gopass insert my/first/secret.
Several basic things can be done with a secret:


  1. List all your secrets – gopass
  2. Show it – gopass my/first/secret
  3. Copy to clipboard – gopass -c my/first/secret
  4. Edit it – gopass edit my/first/secret
  5. Remove it – gopass rm my/first/secret
  6. Move it – gopass mv my/first/secret my/first/secret-moved
  7. Copy it – gopass mv my/first/secret-moved my/first/secret-copy

If this is not yet working although GPG and Git were tested together successfully, please have a look at the following points:

To use credentials from local stores in your browser, there is even a Gopass JSON API that can be configured easily. The Gopass Bridge browser extension (available for Chrome, Firefox and Chromium) can then communicate with Gopass. Learn how to set it up here. If it may be used later, note that it assumes a specific way to structure the credentials.

Setting up and using a team store in Gopass

To get a fresh password store for teams up and running, a Git repository with restricted access to only the planned team members is required. How to initialise a Gopass team store is documented at the bottom of the setup page. Unfortunately it does not like the fact that we created a local store before already. Therefore (until this issue is fixed in the CLI) doing it the manually is recommended. It even teaches us a little more about the simplicity of Gopass.

# initialise a standalone store in some throwaway directory
mkdir /Users/jonas/playground/some-temporary-directory
gopass init --path /Users/jonas/playground/some-temporary-directory
cd /Users/jonas/playground/some-temporary-directory
# initialise a git repository, add remote origin and push
git init && git add --all && git commit -m "store creation"
git remote add origin && git push -u origin master
# clone the store from the git repository as a mount
gopass clone store-name
# if successful, find the mounted store, add a secret & list your secrets
gopass mounts
echo "secret-value" | gopass insert store-name/first-secret
gopass list store-name

From now on, modifying the store by adding, editing or deleting secrets will synchronise with the Git remote.

Inviting team members to the store

As done during the setup, team members can just clone the store from Git: gopass clone store-name. After that, they need to add themselves to the set of recipients and sync this change: gopass recipients add && gopass sync. This is not enough yet since the other team members need to trust the new GPG key and re-encrypt all secrets for it.

An existing member of the store needs to do the following to achieve this:

# sync and see all recipients, including the new member
gopass sync && gopass recipients
# copy the new members key to clipboard and trust it
gpg --edit-key <the-gpg-key>
# now remove and re-add the recipient, followed by a sync to push changes
gopass recipients rm <the-gpg-key> --store store-name
gopass recipients add <the-gpg-key> --store store-name
gopass sync

The new member now needs to do another gopass sync to receive the changes and will then be able to fully use the store.

Integrating Gopass with your applications

As all the credentials for a team’s applications can now be managed in Gopass and accessed via the CLI, secrets for applications can be generated without even touching the disk. The following example shows how Kubernetes secrets can be generated from Gopass and applied to the cluster.

#!/usr/bin/env bash
set -e
[[ `uname` = "Linux" ]] && ENCODE="base64 --wrap=0" || ENCODE="base64"
# apply via: | kubectl apply -f -
# database credentials
DB_USERNAME=`gopass store-name/infrastructure/database/prod/username | $ENCODE`
DB_PASSWORD=`gopass store-name/infrastructure/database/prod/password | $ENCODE`
DB_HOSTNAME=`gopass store-name/infrastructure/database/prod/hostname | $ENCODE`
cat <<EOL
kind: Secret
apiVersion: v1
type: Opaque
  name: application-database-credentials
  namespace: prod
  db-username: $DB_USERNAME
  db-password: $DB_PASSWORD
  db-hostname: $DB_HOSTNAME

Also when it is needed to script against infrastructure, for example when test data is inserted into a database from developer machines, getting the credentials from the password store is handy. Here is a fictitious example in TypeScript for Node.js:

import { exec } from 'child_process'
import driver from 'my-db-driver'
import myTestData from './testData'
export default class Gopass {
    public static async show(key: string): Promise {
        return new Promise((resolve, reject) => {
            exec(`gopass show ${key}`, (err: Error | null, stdout: string, stderr: string) => {
                if (err) {
                } else {
const insertTestData = async (rows: any[]) => {
    const hostname = await'store-name/infrastructure/database/prod/hostname')
    const username = await'store-name/infrastructure/database/prod/username')
    const password = await'store-name/infrastructure/database/prod/password')
    const connection = driver.createConnection(hostname, username, password)
    connection.insertRows('my_table', rows)
await insertTestData(myTestData)

Browsing Gopass outside the terminal with Gopass UI

To maintain Gopass secrets, have a better visual representation and make them available for not-that-technical team members, there was nothing satisfying out there. This is why a couple of codecentric employees decided to develop a simple but yet fancy user interface. It is called Gopass UI and can be found, downloaded and contributed to on Github.

Gopass UI example screenshot


Teams should use password managers at all cost. It is not recommended to touch passwords too often by hand, nor is it safe to write them down in documents on your local machine. Often this results in team members sharing their passwords via plain emails or chat messages.
It is not difficult to introduce basic security rules and mechanisms in a software development team. A simple but powerful and robust password manager like Gopass is a great tool to start with. It is versatile, easy to learn, open source and completely free of charge. You are also not bound to a specific provider and still able to use the files on their own. So, have fun trying out Gopass and stay secure!

As a full stack developer, Jonas is passionate about developing digital products in agile, cross-functional teams. He prefers to use cloud native ideas such as Serverless and managed services from AWS (Amazon Web Services). Originally influenced by Java, he now prefers Node.js, TypeScript and modern JavaScript tooling.


Your email address will not be published. Required fields are marked *