Erin Call

Erin Call

You Can't Spell Engineering Without Erin

Using PGP To Encrypt The Ansible Vault

Over the last week I've been getting rid of the extremely janky Puppet setup I had provisioning my VPS, and replacing it with Ansible. One of the features I really like in Ansible is the Vault, which is a fancy name for AES-encrypted data files. The Vault lets me put stuff like API keys in source control without exposing them to my enemies [1]. Super convenient!

Unfortunately, the Vault is also sort of a pain: every time I want to edit an encrypted file, or do a test run, I have to type my Super Complex Secret Passphrase. I had to do a lot of test runs while getting everything verified, so that got pretty tedious. Additionally, if this Ansible setup were for a project with many developers, I'd have the usual password-distribution problems.

Fortunately, there's another way. Ansible has support for getting the Vault passphrase from a script [2], so if I had some authorized agent that could report the passphrase, I'd be golden. John Knight has a nice writeup on using GPG, but I'm a little uncomfortable with his approach. He stores a PGP-encrypted Vault passphrase in source control, which is sensible, but then decrypts it to a .gitignored plaintext file. That isn't the kind of thing I want to leave lying around. I use full-disk encryption and all, but I'm still nervous, so I've developed a slightly different approach.

First, I generate a super secret Vault passphrase:

pwgen -C | head -n1 | gpg -e -o vault_passphrase.gpg

I'm using pwgen here, but of course you could read from /dev/urandom or whatever strikes your fancy. The point is just to make something nice and unguessable, since humans won't ever have to type it.

Now I make a script called Remember, it needs to be marked executable or Ansible will think its contents themselves are the passphrase.

gpg --batch --use-agent --decrypt vault_passphrase.gpg

I tell Ansible about it by adding a line to ansible.cfg:


The last thing is to make sure gpg-agent is installed and running. Otherwise, I've just swapped "type an inconveniently-long Vault passphrase" for "type an inconveniently-long PGP passphrase," and that's not even an improvement. I've put a 10-minute TTL on my GPG agent by adding default-cache-ttl 600 to ~/.gnupg/gpg-agent.conf, to minimize the window where someone can use my cached private key.

Once I've done all this, I have a real nice situation: my servers' secrets are in source control, but not exposed; I can grant and revoke access with ease; an authorized person must be present to decrypt any secrets; I don't have to type my passphrase over and over and over. As far as I'm concerned, it's the best of all possible worlds!

[1] I don't actually have any enemies. At least, not as far as I know!

[2] Since version 1.7.

Posted on 2014-11-30T21:00:00Z
Posted in ansible, pgp.
comments powered by Disqus