Loading secrets with 1Password’s Developer Tools
I just got a new computer (for the curious, it’s a MacBookPro 16in with an M1 chip, which I am currently typing on—nice so far!), and a couple weeks ago, in anticipation of setting it up, I took a look at my core developer tools repo, dotfiles.
Right after installing Firefox, 1Password, Alfred, and iTerm2, it was pretty much the next thing I put on any computer I intended to use for development work. I’d been wanting to make the repo public for years; I’m very happy with how it’s setup, using dotbot’s yaml config to create symlinks for my main
.zshrcand other useful command line tools.
The one thing that was flummoxing me was secrets: API keys, webhook URLs, passwords, everything you don’t want to share with the world at large. How could I share my repo without sharing those?
Of course it’s easy enough to simply
gitignorean env file, but I’ve deleted local-envs full of keys in fits of pique before, setting myself up for at least 30 minutes of work to regenerate all the secrets I’d lost. No thank you to that. I needed something a little more permanent, but still secure.
Looking at that list of initial software installs above, it occurred to me that one of my other core tools might be the answer: 1Password, the password manager I use both for work and home.
It was the perfect place to store secrets!
But how was I supposed to get them out?
op, 1Pass’s CLI tool! Right in the first line of the description, it purported to do exactly what I needed it to:
1Password CLI allows you to load secrets from 1Password in environment variables and configuration files using secret references, so you don't have to put any plaintext secrets in code.
It took a little finagling, but I figured out a flow I’m happy with.
After adding all my secrets to 1Pass, I created a template env file in the format they describe in the docs. For example:
Then I used
op injectto populate the template with the actual secrets. The
-fflag forces the action, aka removes the typical confirmation step at the command line, and
-ooutputs the result directly to a file instead of to
cat ./local.env | op inject -f -o mysecrets.zsh
Then I went ahead and gitignored the resulting secret-filled file, et voilà, I was good to go!
Now that I’ve cleaned up my dotfiles repo, it’s available to view on Gitlab, and I actually created an oh-my-zsh plugin for working with 1Password secrets that you can modify your own ends.
Remember, safe is sexy! 😉