Keeping secrets in public with puppet

Mon, 10 Feb 2014 18:26:14 +0000

I recently stumbled across dotgpg , which is in essence some scripts to make it easy to securely keep secret files in a public git repo, which are protected by means of having been encrypted (usually for multiple recipients). It comes with capistrano glue for decrypting them again and sending them to your production servers, but it doesn’t quite fit my masterless use case where everything happens on the same box and there isn’t the same notion of a ‘target system’

But it set me to thinking: what if there was some kind of gpg agent that let you type in your key once and used it for multiple decryptions (turns out there is) and what if you then wrote some custom puppet function, let’s call it decrypt, so you could then say

  file {'/etc/wpa_supplicant.conf':
    content=>decrypt("templates/etc/wpa_supplicant.conf.gpg"),
    owner=>root,
    mode=>0600
  }

and everything would Just Work. Well, turns out I did and you can and (as far as I can tell) it does. The custom function is as simple as creating the file puppet/parser/functions/decrypt.rb inside /etc/puppet (or wherever) containing

module Puppet::Parser::Functions
  newfunction(:decrypt, :type=>:rvalue) do |args|
    filename = args[0]
    `/usr/bin/gpg --use-agent --decrypt #{filename}`
  end
end

and now at the expense of a slightly more convoluted puppet invocation

$ sudo  make -C/etc/puppet/ GNUPGHOME=$HOME/.gnupg GPG_AGENT_INFO=$GPG_AGENT_INFO

I can put my wpa network configuration (and my jabber passwords, and smtp client passwords, and some other stuff I can’t right now remember what it is but am sure exists) alongside my all my other configuration instead of either having to do something silly with git submodules or rebuilding it by hand. Am now furiously trying to memorise my passphrase.

Better error checking would be nice, so that it doesn’t overwrite a perfectly good config file with an empty one if the gpg stars aren’t all aligned, but that is left as an exercise for next time.