Prologue
At JustWatch, we try to combine technical excellence with an awesome user experience - not just for our website and apps, but also for our internal tools.
For personal password management, there are alotof viable solutions available.
But unfortunately, none of the available solutions really cut it forworking in a team - and we tried a lot of them.
Now you might say sharing passwords is a bad idea in the first place and you would be completely right. Wherever available, you should absolutely use real user and service accounts, but in the end, reality will probably catch up with you at some point.
Now where do you store all the smaller supplier accounts that support no real ACL? Where to put that production certificate securing your app push notifications or your Kubernetes cluster? That AWS root password you vouched never to use but want to have there just for backup? Do you put it on paper, in a safe? What about a fire, or the infamous bus factor?
Building a company in the real world, we eventually had to settle for something. In a colorful and distributed team, cross-platform was an absolute must, and we really really wanted an open source solution for storing some of our most sensitive data. The venerable KeePassX on a shared drive was a compromise some of us had used in the past - but with a binary database, it was hard to keep track of owners and changes, and collisions could lead to corruption.
Cue “pass”
That’s why we were all excited by “pass” when it arrived.
Pass has the wonderful philosophy of being a simple command-line application first - and leaving the hard stuff
to the most mature solutions available: gpg
for cryptography and git
for managing distributed state.
pass
is built with security in mind and still very easy to use.
It stores each password in a gpg
encrypted file that lives in the regular directory on your drive.
This directory can optionally be managed using git. This makes it very easy to share a passwordstore
with other people.
There is one slight drawback to all the simplicity, and that is an information disclosure inherent to the design: pass
stores all folder and file names in clear text, so even if you fully trust GPG, you should probably not put this
repo into a public place like Github, because this may expose your account names and other metadata.
We felt this was an appropriate tradeoff to make in our case, went all-in with the tool in early 2015 (hosted on our internal Gitlab) and were generally very happy with our choice. Nevertheless, the list of issues and feature wishes grew larger with time.
Trouble on the horizon
In the spirit of Open Source, we felt like contributing back to the community, but we quickly discovered that this was easier said than done. First, the project is curated in a traditional mailing-list based approach that was pretty unapproachable compared to a modern Github based workflow.
Second, with all due respect to the original author zx2c4 (who is currently working on the very promisingWireGuard project), the project proved to be a wild bunch of hotwired bash
scripts
that mostly looked like they were written as a one-off job. Following the code was hard and extending
it even more so.
So while our SREs were definitely no strangers to bash
, all of this felt like a good opportunity for a rewrite.
Introducing gopass
So you might have grown tired of the usual “XYZ rewritten in Go (Rust/Nim/Haskell)” post, but bear with us for a minute.
While a naive rewrite with exactly the same features would usually be silly, we took the opportunity to do a clean room re-build from scratch, based on a modern GitHub based Open Source workflow, including tests and adding lots of useful features on top - all within a cleaned-up internal architecture - and we hope you enjoy it.
But that’s not the end - we have quite some plans for gopass
, and we’re releasing our first milestone to
the public today.
Let’s have look at what’s in our 1.0 milestone:
- 100%
pass
compatible - install it and work with your current setup as before - Multiple stores: Combine several work teams and your private store!
Works with binary data: Certificates, images, you name it…<- bumped to 1.1.0 due to interface change- Git Auto-Push & Auto-Pull: Never forget to share after editing credentials
- Great Usability (with much more to come)
- Bash and Zsh Autocompletion
The “pass” compatibility promise
At the current point, we try hard to maintain full pass
compatibility and will later on require explicit opt-in
to break this promise going forward. This means that you are free to switch back and forth betweenpass
and gopass
for now. You can even leave it up to your team members to use
whatever implementation they prefer - all pass
based ecosystem including apps and migrators should continue to work.
Multiple stores
Because pass
is so amazing, a few of us wanted to use it for their private
credentials as well. While working with just one password store is very easy withpass
, working with multiple ones is not convenient at all.
It’s possible to hack it with bash aliases, but this isn’t just ugly, but will disable autocompletion as well if not adding other hacks on top.
Enter gopass multi-store support
. A concept most UNIX/Linux users are familiar
with are filesystem mounts. So we thought: why not having a password store act
like a virtual filesystem?
gopass
support mounts
of password stores into your default password store.
They act and feel pretty much like a regular filesystem mount, but every mounted
store has its own recipients and git repository. This makes it very easy
to organize your credentials into several groups of authorized people.
# Mount an existing store
gopass mount test ./password-store-test
# Show a password from the store
gopass test/server/root # is "server/root" inside pass repo
# Get a new store from a repository
gopass clone git@git.example.com/examplestore bar
# Show a password from the store
gopass bar/database/blog # is "database/blog" inside pass repo
# Show mounted stores
gopass mount
# Unmount a store
gopass mount -u test
Binary data
Binary data support has been pulled from the current release due to interface improvements and will be released soon!
Git Auto-Push & Pull
While working with pass
in teams or from multiple machines it’s easy to forget
to git push
your changes to a repository. It’s very embarrassing if you can’t
access an important secret while being on the road, only because you forgot to
push from that other machine in the office.
To mitigate this, gopass
provides the autopush
feature. Just enable it and after eachgit commit
, it will automatically push to your repository. If your prefer to pull
before push (to avoid collisions), we can do that, too. Just enable autopull
as well.
gopass config autopush true
gopass config autopull true
Installation
We provide pre-built packages for a number of platforms:
macOS
# If you're a Homebrew maintainer by any chance, feel free to pull the formula into the main repo
brew tap justwatchcom/gopass
brew install gopass
Debian and Ubuntu
wget https://www.justwatch.com/gopass/releases/1.0.0/gopass_1.0.0_amd64.deb
sudo dpkg -i gopass_1.0.0_amd64.deb
ArchLinux
pacaur -S gopass
Other operating systems
Please visit https://www.justwatch.com/gopass/releases/1.0.0/ for a list of binary releases or go get github.com/justwatchcom/gopass
from source.
Wrapping up
We hope you’ll find gopass
to be “The slightly more awesome standard unix password manager” we set out to build - enjoy and tell us what you think. Feel free to open an issue with us with your feature requests or offer pull requests.
This project is available on GitHub right now and we promise toactively maintain it for the foreseeable future.
This post was brought to you by Dominik Schulz, Head of Infrastructure, and Matthias Loibl, Junior SRE. If you like to work with Go, awesome open-source projects and security, we’re currently hiring Software Engineers and SREs.