A different way of encrypting data is proposed through Chef Vault, and this does not require you to include the key somewhere in the code. The concept is elegant and simple: shared key encryption is done for each and every existing Chef node through their already existing client keys. This way, only the nodes allowed to access the data can decrypt it—each with their own private key—ensuring no clear-text shared keys are being sent, like with the classic encrypted data bag scheme.
To step through this recipe, you will need:
We'll build on the previous, already existing, mysite
cookbook; however, any other situation will work similarly. Instead of using the us-east-1
item from the aws
data bag, let's create a new eu-west-1
item, very similar to the other item for us-east-1
in data_bags/aws/eu-west-1.json
:
{ "id": "eu-west-1", "aws_access_key": "an_access_key", "aws_secret_key": "a_secret_key" }
As we know, the data will be encrypted for each and every running node's public key. It means we have to filter hosts based on a search. I propose, that you search for every node using search(*:*)
; however, feel free to limit to whatever is more secure or appropriate for you, such as tags or roles, like search(tags:aws)
or search(role:mysite)
:
$ knife vault create aws eu-west-1 --json data_bags/aws/eu-west-1.json --search "*:*" --mode "client"
The companion to knife vault
is the chef-vault
cookbook. We'll use it to easily access encrypted data in our recipe. If you're using Berkshelf to manage dependencies, don't forget to add the cookbook where required (either metadata.rb
or Berksfile
). In the aws.rb
file, include the chef-vault
recipe and set aws
to the result of the chef_vault_item
helper search:
include_recipe 'chef-vault' aws = chef_vault_item('aws', 'eu-west-1')
If the node making the request isn't allowed to decrypt the data with its private key, we'll get an error. If the node can decrypt it, like we did previously with traditional data bags, the data will be available for use:
template "/etc/aws/credentials" do source 'aws.erb' owner 'root' group 'root' mode '0600' variables( aws_region: aws['id'], aws_access_key: aws['aws_access_key'], aws_secret_key: aws['aws_secret_key'] ) end
In the end, the /etc/aws/credentials
file is populated with valid unencrypted data:
$ sudo cat /etc/aws/credentials [eu-west-1] aws_access_key_id = an_access_key aws_secret_access_key = a_secret_key
Using Chef Vault, no shared key has ever transited in clear text, and only filtered and existing nodes can decrypt data that has been encrypted specifically for them. Much more can be done with this tool!
3.138.122.11