Password Management with gopass password-store, gopass bridge, and Pass for iOS

While I’ve been using passpie for some time as a CLI password manager, it lacked mobile and browser integration and an ecosystem for leveraging other tools. This is what I replaced it with duplicating the functionality range you’d see in commercial apps like 1Password and Dashlane, while being free, open source, cross platform, more portable, and developer-friendly.

Often, oldest solutions to problems are the best. They provide a common, battle-tested standard for everyone to work with. Pass, the standard unix password manager has been around for ages and follows the unix philosophy of a simple, robust tool which does one thing well and integrates with other tools for composable toolchains.

Simply, each password lives in a gpg encrypted file whose filename is the title of the resource whose information it holds (and directory is a referrable semantic category of files eg. banks/citi, banks/ing). It’s practical, flexible, secure to store in the clear, and by following simple conventions, gives you great security on the CLI and with other apps. This is how you get it to support browser login/password fill-ins as well as how to get it working with an iOS app to have stuff on the go. You can also easily have syncing back and forth password system without the need for using a commercial service. I’ve been using it for over three months now and finding it better than commercial services (though may be philosophically biased).

Prerequisites

  1. Terminal and CLI comfort
  2. gpg with a personal private asnd public key generated (plus know its basic workings)
  3. git version control system (engineers and data scientists should be using this anyway)
  4. A github account (or other git-based cloud provider, GitLab etc.)

While not absolutely necessary, basic understanding of public-key/assymetric cryptograhy is gonna make this more comprehensible (if you’re a dev of data scientists, this is useful for you to understand anyhow.). I would not recommend attempting replacing a commercial product you may be using without understanding this, as you might (possibly) compromise yourself. There are great materials out on the internet explaining this in more details, and to be honest, it’s one of the underlying innovations that makes the modern internet possible, so getting a solid grok of how encryption actually work is a good use of your time.

We’ll be setting up GoPass, the GoPass Bridge, and then showing you how to get Pass for iOS working with syncing changes through Github.

GoPass password manager

Setting up GoPass

While pass is fine, there is a simpler, faster, “slightly more awesome” binary version of it, gopass which mirrors its functionality and API as well as providing some team features if that is valuable to you. It works great, is faster, and has git integration by default, which is a handy touch. Also, the gopher logo is way cuter, so it wins (the documentation is also excellent imho). The 1.8.6 version is available for most Linux flavours through their package managers at time of writing, and if you are handy with golang already you can compile from source with go get github.com/gopasspw/gopass. If, like me, you’re on OSX, use always-useful Homebrew package manager and install it with brew install gopass. Installation sorted.

For convenience, and interoperability, I also recommend symlinking the pass command to gopass. On my OSX system that meant:

ln -s /usr/local/bin/gopass /usr/local/bin/pass

Check to make sure everything is working with pass --version and gopass --version which, at time of writing should yield a response of gopass 1.8.6 (often followed by a hash and date and go version os and architecture after it).

Let’s get set up. 2 commands. Type:

pass init email_of_key_you_want_to_use@example.com
pass git init

This initializes your password store to a specific gpg key (set by email though you can also use the unique gpg key id) at the default location of ~/.password-store and then initializes a git repository there. For the sake of sanity, I use my default passphrase-protected encryption key in gpg tied to my main email though there is nothing stopping you from having a completely separate keypair for the password store. Make sure your gpg key passphrase is strong. It’s effectively the master key for your password store now. Pass is basically some convenience functions around a directory of encrypted files. If your passphrase isn’t strong, reset it (look up how to do that in the gpg guide).

Note that GoPass also brilliantly makes a git commit every time you make a change to your password store (and if a remote is set, will push your changes to your remote git repo so automatically backing it up and providing a way to keep other apps/computers in sync.). Since these files are effectively gpg encrypted files and you store the main key (with password) back on your machine, you can also store the entire repo in the clear on a cloud git repo without fear of compromise.

Let’s create a password store entry. There is a specific format to recording password entries you should use so that it will work with tools like the GoPass Bridge and Pass for iOS. Let’s use the multiline option (-m or –multi) to show that.

pass generate -ex perso/fave-ecomm-store

This will generate a (memorable) xkcd style password with the -x/--xkcd switch and fire up the default terminal editor on your system via the -e/--edit switch. For most people that will be vim or nano. Regardless of editor, you want to organize your fields in your entry this way:

aide simile bobtail undermost
---
user: your_mail@example.com
url: https://favestore.com
notes: Anything you want here.

Note the triple dash to separate the fields --- and then user and url (notes is optional, I put that in for myself since otherwise a year from now I’ll be wondering when I changed this last.). You do want to follow this yaml convention though. This will become important when you want to use the GoBridge for auto logging into site via your browser and with Pass for iOS. (note: in the generate example, the initial perso/fave-ecomm-store gets pushed to the upstream repo before you add in the other details, but once you save the additional details those are also are encrypted and pushed up. Note a lot of the git operations happen in the background.). Note: If you haven’t set up a git remote yet (see next section), gopass will complaing there is no remote set up.

Now if you type pass (or gopass if you did not use the symlink advice), you should see the following:

gopass
├── perso
│   └── fave-cloud-store

To retrieve your password, simply type in pass -c perso/fave-cloud-store and you’ll be prompted for the password to unlock your gpg key. Then the information will be printed out to the terminal and copied to the clipboard for a default 45 seconds before being cleared.

pass rm perso/fave-cloud-store

is used to delete that example and return your store to its pristine state. If you are using other password managers there are a whack of converters on the pass unix store page to move everything over from those vaults to pass. I wrote a small script to move entries from passpie to password store myself, but since everything is plain text, the process is pretty painless either by entry or a little typing.

You can also use common command line utilities to pipeline to pass. For example, want to know how many passwords you have in your store? Use the handy wordcount command on your unix-based system:

pass | wc -l

Surprised to find I had 98 entries even after cleaning up dead entries when I migrated (remember to subtract one from the result due to the gopass line being at the top.).

Using GoPass with Github/Gitlab

Version controlling your password store is a brilliant idea and keeping it in the cloud provides both backup and synchronization since its encrypted in the clear is then a no-brainer as long as your secret key’s passphrase is strong and the secret key locked down to your main machine (or otherwise similarly protected.). Gopass integrates git by default which means that what manually you’d do with pass, you get for free with gopass. Changes to your password store get pushed automagically to the cloud (once you provide a git remote destination. See below for that.

This is what you’d do for creating any repo for any code base whether you’re using github, gitlab, or any other git capable server. Taking github as the example most people will need to use (though the same goes for gitlab on the token auth.):

Create a new private repository on github, let’s say password-store-example.

On the command line back on your machine in the .password-store directory, then issue the following two commands:

git remote add origin git@github.com:your-repo-username/password-store-example.git
git push -u origin master

You now have your passwords in the cloud, encrypted in the clear. The other thing is that not only can your other machines use the store (for example, if you have a work setup and a home setup or like me, are often bouncing between OSX and Linux) but also tools like Pass for iOS can use it too.

This is effectively fire and forget. Once you’ve done this, you can leave it in place. Until you want to use the password store on another machine (in which case you git clone this to ~/.password-store and make sure your gpg keys in ~/.gpg for the store are available on the machine in question. Then just set up gopass).

Again, this all automagic with GoPass (and Pass for iOS), as well as providing a disaster recovery option for your passwords if your machine goes down (as long as you can get into your github repos.).

Setting Up Your Browser for GoPass Bridge

Let’s face it, a CLI password manager is handy but what you generally want it for is logging into the plethora of sites you have username and passwords for (as well as generating those passwords for you.). That’s where the GoPass Bridge comes in and handy extensions for Firefox and Chrome.

Gopass already has native messaging built-in. So, there is nothing to install, this is just a matter of installing an extension and (depending on your tastes) possibly altering gpg to support a pop-up window for the inputting of your gpg key password (I keep using mine with the terminal entry.)

There are extensions for both Firefox and Chrome/Chromium available.

Follow the usual steps to install extensions and you’re in pretty good shape with the cute gopher logo now in your toolbar.

The easiest way to enable this is then to use the CLI command gopass jsonapi configure and follow the instructions there. After you’ve answered all the questions and the shell script it installs itself in ~/.config/gopass and you’re ready to go. Test it out and make sure it works. if you want a graphical popup for the browser to come up, you’ll need to install a separate brew package in some cases if you’re not using the GPG Suite of graphical tools already (I stick to the command line.).

Setting Up Pass for iOS

You’re in great shape already. You’ve got a simple, robust, almost bullet-proof password store on your machine and in the cloud based on rock-solid cryptography through gpg. What happens when you’re not on the go though? Or want to read an Economist or NYTimes article and it is demanding a login? This is generally where commercial products have shined, with greater resources to throw at mobile developers, so I was impressed to find Pass for iOS, an excellent (and free) iOS app available. (I can’t speak for the Android version of similar apps, but this is what I’m using.).

Effectively, you can think about the setup for Pass for iOS as two parts:

  1. Configuring and getting your git repo of encrypted passwords
  2. Setting up your gpg keys to be able to decrypt those

First off, get into the App Store and search for “Pass - Password Store”. You know you’ve got the right one if its by Mingshen Sun (who has done a great job here. Send him a nice message if you can. He deserves it!). The code is also available on Github if you’re interested in perusing it (I was).

The setup for Pass is a bit trickier, because you need to make it see your github repo, as well as it needs your gpg secret key in order to decrypt things (which should be protected by a complex passphrase so you’re good, security wise. I cannot emphasize this enough as you’ve noted.). Surprisingly, other than a few moments of head scratching when I did the original setup (mostly caused by a change with Github a while back) this was rather easy to do.

Configuring your git credentials

Now you’ve got the Pass for iOS app, Open it on your iPhone and go to Settings.

In the General tab, to make your life easier, I’d strongly recommend making sure the “Remember Git Credential Passphrase” is in the On position as well as “Show Folders”. For general security reasons, I’d turn off “Remember PGP key Passphrase” and keep it off (though note, this means you’re entering in your password each time you want to decrypt though I find this an easy bargain security-wise.).

Go to Password Repository. There’s one semi-complex thing to do here and that is surrounding the “Password”. In the Git Repository URL, go to your github account and grab the https version of what you would clone and copy it to your clipboard via the handy clipboard button in Github. On your phone, take advantage of the OSX handoff feature and simply paste that into the field. Boom. If you’ve disabled that feature for some reason, you may need to type it in manually.

Keep the branch name as master and put in your github username for this repo.

The Authentication Method is the tricky part. This is specific to Github mostly and what took me the most time to figure out. Github (and Gitlab) moved off using passwords over https in favour of using specific API tokens.

If you’ve never done this before (and even if you have I’d set up a separate token for the app), go to Github and in your Account settings, go to “Developer Settings”. On the screen, click on the menu item to the left that is labelled “Personal access tokens”. Click the “Generate new token” button and name your token something explicit (mine was “GoPassforiOSPasswordStore”). Give it only sufficient rights to pull and push to your repo.

Copy the actual token and then go back to Pass for iOS. Hit the “Clone” in the top right hand corner and you should be prompted for your “password”. Paste in the token (which OSX should make available to your iOS clipboard via Handoff.).

Go back to the main screen and you should see all your passwords populate into the app. Tada! You now have a syncing password store with your iPhone. Also, passwords you create in Pass for iOS will also sync with github when you pull down the main screen to both push and pull.

Configuring your gpg credentials

Now, of course, you have the encrypted files on your phone, but you need to be able to decrypt them. This is where the gpg part of the setup come in: you need to provide your public and secret keys to the app in order for it to be bale to decode your password store on your phone.

This will require a bit of gpg command line work. So, head back to your computer: Crack open your terminal and get to the command line.

There are two commands you need. I suggest saving the key to file rather than terminal even though we’re just copy pasting (my terminal pasting went awry the first time.).

🚀 gpg --export -a your_key_id > ~/Desktop/public_key.pub
🚀 gpg --export-secret-keys -a your_key_id > ~/Desktop/secret_key.sec

The -a switch ascii-armours the file so you won’t have any strange character transfer issues between systems.

In the Pass for iOS app, tap Settings, and pick the “PGP Key” option. You’ll get a menu lists of options (Download from URL, ASCII-Armor Encrypted Key, Load from File, iTunes File Sharing, Remove PGP Keys.). The easiest here (at least with OSX) is to choose ASCII-Armor since we can take advantage of the Mac’s ability to copy-paste from OSX to iOS. On a Linux machine, you’ll need to Download from URL or Load from File.

Open your public key in your text editor of choice, copy the text, and then paste it into the Pass for iOS public key text box.

Do the same for your private key.

(note: there is a cool scan the QR code feature in there I have not had a chance to try out yet, but want to amend this post at a later date with that since it seems a nifty way to handle the transfer problem seamlessly and in a cross-platform manner.).

You should now be all set up with your keys.

To test, go back to the Passwords screen. Pull down on the listing to force the system to sync any passwords from your repo (or to sync any passwords you have created back to your repo) and pick one of your password listings. You should get a nice password box come up in Pass for iOS. Type in your private key’s password and you should be able to see your listing for the entry.

Fin

You should absolutely be using a password manager. The benefits to your security are legion and it reduces friction for enforcing good password hygiene (Pass can also generate sufficiently complex passwords for you.). With a little time for the one-time setup, you can save yourself the monthly or annual fee on a password manager, have a much more future proof, self-hosted, robust, and (imho) more secure set up than commercial password managers from free, open source and proven tools you already have on your system.

As we move our digital lives increasingly into the cloud, we should be more concerned about self-hosting and controlling our data and its formats, rather than entrusting too much to commercial services. Where security and privacy are concerned, it doesn’t take a lot to use rock-solid and robust systems and common data formats or conventions to put together a smooth end-to-end workflow that works seamlessly as well as ensuring control and security remains in your hands.