Introducing Summon – Get Your Secrets Into Source Control
| DevOps |
Today we’re releasing Summon, an open-source tool to help developers and sysadmins improve workflows that involve access to secrets. Secrets are hard. We can’t check them into source control, even though they are a dependency of every application. We also can’t treat secrets like configuration because storage and retrieval needs to be secure. Summon is a response to this in-between land.
Summon reads a file called secrets.yml, which is a mapping from environment variable names to secrets identifiers. Using a pluggable provider, it retrieves the values of those secrets and makes them available in the environment of a child process which you specify. The provider’s job is to retrieve the value of a secret based on its identifier. The process only needs to be able read environment variables: a webapp, deployment script or chef-client run, as examples. Once the process exits the environment variables do not remain on the system.
Read more about the problem in our previous post.
Let’s say we have a Fabric script to deploy our webapp1 to AWS. We want to record the status of the deployment for inspection later, so we’re inserting a record into MongoDB. We’ll need AWS keys and a MongoDB password to accomplish this. Let’s capture this in a secrets.yml file.
We can check this file into Git, there are no secrets in it. Now, anyone who clones the repo can immediately see which secrets the project requires and where they come from. The identifiers in secrets.yml are interpreted by the provider (driver), so they could be Conjur variables, names of secrets in the Keychain, etc.
Now we can wrap the Fabric call with Summon to provide these credentials.
summon --provider ./summon-conjur -f secrets.yml fab -e prod,webapp1 deploy
-e tag is specifying the tags of instances we want to deploy to, à la awsfabrictasks.
Summon uses pluggable providers to fetch secrets. A provider’s job is easy: given the identifier of a secret, return its value on stdout or an error message on stderr. We’ve written providers for Amazon S3, Conjur, and the OS X Keychain so far. You can download them from their respective GitHub pages. You can also write your own provider in any language; it can be as simple as a shell script. Summon takes care of interpreting the output.
Summon will also auto-discover providers placed in
/usr/libexec/summon/. The path to a provider can also be specified via the –provider flag, as in the example above, or with the environment variable
Most of our development in-house is Ruby. The language allows us to be expressive and get things done quickly. Packaging Ruby applications, alas, is not fun. summon and the
summon-conjur provider are written in Go because it allows us to package them as a single binary. Therefore, installing Summon takes only two steps: download the release for your platform and unzip it onto your system.