Encrypting Secrets with Chef Vault
At Collective Idea we use Chef for server configuration, not only for our own products such as Harmony and Dead Man’s Snitch but for our clients’ needs as well. One important aspect of server configuration is handling secrets: service APIs, passwords, user accounts, etc. Secrets like these should not end up in a source repository, but they still need to be managed in a reliable fashion to ensure developers can always find them and make changes as needed.
Chef’s Encrypted Data Bags are a good first step for secret protection. With this system, data bags are strongly, symmetrically encrypted, but there are a few downsides. Most importantly, the encryption key must be manually shared between the developers and the servers. Also, keeping multiple encryption keys for multiple environments is tedious and error prone, and it’s not easy to revoke a developer’s access once they have the key.
The operations team at Nordstrom took it upon themselves to improve this situation and released Chef Vault, a layer on top of Encrypted Data Bags that hooks into Chef Server’s public/private key management. Chef Vault lets developers specify exactly who and what has access to individual encrypted data bag items. Installation is as simple as gem install chef-vault
with no other configuration necessary. Chef Vault is well documented but I’ll go through the most common commands here to show how easy it is to keep your secrets secure.
Creating a Vault
Vault creation is very similar to data bag creation. Specify a Vault name, and Item name inside of that vault as well as the default JSON data to go into the vault. You can optionally specify a node search, and/or a list of Chef Server users who should have access to the vault.
knife vault create [vault] [item] '{}'
knife vault create [vault] [item] '{}' -S 'search' -A 'user1,user2'
Editing a Vault
Assuming the EDITOR
environment variable is set, editing a vault will open the decrypted JSON into your editor, re-encrypting changes when the editor is closed.
knife vault edit [vault] [item]
Adding Nodes or Users to a Vault
As new servers are added, old ones are removed, and people come and go, you’ll want to ensure the encryption permissions are updated accordingly. If the new nodes match existing Search settings or a user has replaced their keys, just use refresh
:
knife vault refresh [vault] [item]
If the settings of the Vault need to change, say removing or adding a user to the vault, use the update
command instead. Do note that the -A
option must always be the full list of users allowed to access said Vault.
knife vault update [vault] [item] -S "new search" -A "user1"
Cookbooks
Once the Vaults are built and uploaded to the server, accessing the Vault information in your cookbooks is as follows:
chef_gem("chef-vault")
vault_data = ChefVault::Item.load(data_bag_name, item_name)
Configuration
In all of this, Chef Vault has been managing the raw JSON files local to the developer. These need to then be pushed to the Chef Server as data bags (knife data bag from file [data bag] [file]
). You can tell Chef Vault to instead work directly with data bags on Chef Server by setting knife[:vault_mode] = "client"
, however we prefer the default mode, "solo"
, as that lets us keep the canonical encrypted files in source control and easy to share with the team.
Chef Vault is slick and is the best solution I’ve seen yet for encrypting your server secrets in Chef.
Comments