Conjur and Chef: Baking in Security


April 20, 2015 | DevOps | Dustin Collins


We have just released our official cookbook to the Chef Supermarket!

To see this cookbook in action, check out our brand-new SSH demo.

We wrote this cookbook to make it simple for you to apply a Conjur identity to nodes you are already managing with Chef. One benefit here is that accessing secrets in your Chef runs becomes much simpler if they are run on a host with a Conjur identity. Instead of managing encrypted data bags and their decryption keys, you can pass in secrets as environment variables and use ENV['mysecret'] in your recipes.


Another benefit is that you aren’t using Chef to do SSH access management. Instead, you are organizing your security layout in a role-based manner: users into groups and hosts into layers. This means that when you need to add a new user or host, escalate privileges temporarily or remove users or hosts from your topology you don’t need to worry about modifying data bags and pushing them through your release process. Permissions changes happen instantly via Conjur’s replicated web services.

Finally, you have an audit trail. Any access to secrets, SSH logins/logouts and sudo calls – they are all logged and accessible via the Conjur CLI, UI or API.

I want to highlight the usage pattern we suggest for setting up your hosts with Conjur and Chef. This same pattern can be applied for other CM tools you may be using. There are three steps in this workflow.

1. Foundation

Include the conjur::conjurrc recipe in the base cookbook for your organization. This recipe configures the connection to the Conjur server endpoint and establishes SSL verification. Set attributes for your Conjur endpoint. None of these attributes are secret – you can check them into source control.

If you want Conjur to manage SSH access, include the conjur::install in your base cookbook as well. This recipe installs and configures packages required for Conjur SSH.

If you want to install the Conjur CLI on your hosts, include the conjur::client recipe. You’ll then be able to use the conjur env command for easy injection of secret as environment variables into your scripts and applications.

This base configuration can be baked into an image for faster launches.

2. Identity

Once you have your base image, you need to apply a Conjur identity to your host. How you do this will depend on your infrastructure. We use AWS internally so I’ll briefly walk through we apply identity to our Jenkins executors.

We created a layer named ‘build-0.1.0/jenkins’. This layer has permissions to read different secrets needed by our CI jobs. Using host-factory, we created a token for hosts to enroll into this layer. This token is passed as a parameter to the CloudFormation stack that defines an auto-scaling group of EC2 instances. The user-data for the instances is a bash script that then uses this token to create and apply a host identity on instance launch. Instances launch, execute their user-data script and can then interact with Conjur.


A Conjur identity can also be supplied entirely through environment variables. We’ll cover this in an upcoming post on applying identity to Heroku applications.

3. Configure

This step is only necessary if you want to manage SSH through Conjur. Include the conjur::configure recipe in your application cookbooks or roles. This recipe applies the Conjur host identity to finish the machine configuration.

In summary, applying Conjur identity to a host means applying base configuration, giving the host an identity and then running any post-identification steps necessary for your organization’s setup.

Our new SSH demo walks you through all three steps above interactively. And, as always, pull requests welcome!



Share This