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.
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.
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:
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 promising WireGuard project), we were surprised to see a software project written entirely in bash. 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.
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:
passcompatible - 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 between
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.
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 with
pass, 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.
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?
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 firstname.lastname@example.org/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 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
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 each
git 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
We provide pre-built packages for a number of platforms:
# 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
pacaur -S gopass
Other operating systems
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 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.