pip install secureconfig

Back in January at Invitae, in response to an internal security audit, I took on the task of coming up with a set of Best Practices For Not Getting Instantly Pwned When Someone Leaves Their Laptop On A Plane Or Something.

What I found, in addition to lots of other things, was that the Python world lacked a sturdy, well-constructed module that allowed developers to keep the configuration management idioms many have baked into their code (e.g. ConfigParser and JSON) while keeping sensitive stuff out

TL;DR — I found a huge security-usability hole in the Python world, so I patched it, and you can RTFM and try it out here:

pip install secureconfig

The idea behind secureconfig is to make it dead simple to encrypt sensitive data that you might like to store in configuration files — API tokens, passwords, etc — and to do it in a way that makes the most secure default choices for you.

I sort of cheated on that last part: I met some of the guys who work on pip install cryptography at PyCon2014 and realized they’ve already got that problem surrounded. So secureconfig uses cryptography’s “Fernet” recipe, which is really just a way of bundling up a bunch of choices relating to AES-128. Go read there, if you’re curious.

The way secureconfig makes encrypted configuration files easy is by providing an interface that gets the encryption steps out of the way of your “real code”. All you need to decide is where to store the private AES-128 key (that secureconfig will happily generate for you if you don’t have one yet).

You might say, “aren’t you just passing the buck to another config file?”

Yes, that’s technically true (the best kind of true!). But it comes back to the usability issue, especially when it comes to teams of developers sharing configuration files.

Within the industry status quo, sensitive data is stored in the clear and protected only by the will of every individual developer to avoid at all costs accidentally committing the “secret” config file to a repository.

When your sensitive data is encrypted in config files, then your imperative becomes keeping a single string of information (the key) safe. We’re finding that it’s far easier, usability-wise, to standardize the name of the key file (e.g. config.aes.key) and add *.key to a repo ignore list than it is to make sure that all types of config files are well-represented in our repo ignore lists.

It’s also nice to be able to keep config files under source control. Non-sensitive data do need to be changed from time to time. And when sensitive data change, you can still see that change reflected in the encrypted strings, even if you can’t tell at a glance whether Joe Schmoe committed bogus credentials that broke the deployment (you’ll find out another way, I’m sure).

And if you don’t like keeping keys in files, that’s cool — secureconfig lets you read and write keys to environment variables.

So, if you like using Jenkins, for example, you can set up a deployment that acquires all of the files it needs from a repository, and then the deployment engineer can manually lay-in the private key within the Jenkins configuration to set any arbitrary environment variable name you like.

All you have to do in your python code to be able to read the encrypted strings, assuming you have the environment variable set with your key, is the following:

from secureconfig import SecureConfigParser

config = SecureConfigParser.from_env('NAME_OF_ENVIRONMENT_VARIABLE')

That’s it. Your config then works exactly and seamlessly like any other ConfigParser you’ve ever used. Oh, and if you don’t like ConfigParser, there’s SecureJson too.

Go take a look at the docs or check out the code, there’s more to it than that! This is just an intro.

Or you could just pip install secureconfig and give it a try.

ps. I <3 the "pip install libraryname" linguistic construction. Absolutely brilliant: it succinctly identifies the library as belonging to a certain language (python) while simultaneously assuring the reader/listener that the library can be installed in a certain way. pps. This is the first piece of FOSS I have ever unilaterally published that makes claims to "security". I am hoping for heaps of criticism. Go ahead, see if you can overflow my buffer, I can take it!

Share and Enjoy

  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS