I’m using Puppet’s Environments to separate out domains of control. Each Environment is cloned from Git repository and starts out with our basic configuration, but each IT group needs the ability to add their own configuration which includes sensitive data that should not be exposed to other groups.
The problem is that Puppet uses x509 certificates to handle identify and authentication very well. But authorization for specific environments is not present. So, once one IT team sets up a Puppet client in their environment, there’s nothing to stop them from pointing at a different environment and potentially acquiring another group’s sensitive data. Puppet’s interface is a RESTful API so if you can figure the location of a configuration file its not hard to use the curl utility to fetch it.
I’m using Passenger via Nginx to run the Puppet Master in production. I’ve recently been growing fond of Ruby and Rack. Thanks to Google, I found the following presentation for securing and extending Puppet that lead me to learning more about Rack and how to shim in some of my own middleware.
I starting modifying my
config.ru file to implement authorization
(with a Z) for environments. The Puppet REST API always starts out with
the environment and makes it easy to use a regular expression to grab.
I have a database of each machine what what access they should have. So
I have all the information to determine if you are authorized for a
specific environment and now the place to code that in.
This does depend on my Puppet certnames being of the form FQDN-UUID.
Where the UUID is a unique identifier given to each machine. Makes it
very handy to find things in the database. Below is my
my Puppet Master. I hope it might inspire others to extend Puppet for
their own needs.