This is because those cookbooks choose not to enforce the pattern in which encrypted data is stored. In the past, encrypted data bags were the only way to store encrypted information. However, now there are great tools like Chef Vault and Citadel (to name a few) that give users a finer-level of security and granularity.
In reality, these should not be stored as node attributes, as node attributes are persisted back to the server. However, there are two things to consider:
- Use the run_state
You can see this pattern in the Jenkins cookbook - and here's the commit where we introduced the feature. The run_state persists only for the duration of that Chef Client run, and only ever exists in the memory of the Ruby process. This is a value you would set in your wrapper cookbook, for example:
node.run_state[:jenkins_private_key] = 'whatever'
For ultimate flexibility, the Jenkins cookbook makes no assumptions of how you set this private key. It is not tied to any particular implementation. This makes the cookbook much more flexible, while reducing the number of testing pathways.
node.run_state[:jenkins_private_key] = encrypted_data_bag_item('foo', 'bar') # Using Encrypted Data Bags (+ Chef Sugar syntax)
node.run_state[:jenkins_private_key] = chef_vault_item('foo', 'bar') # Using Chef Vault
node.run_state[:jenkins_private_key] = 'a plain text string' # Using a plain-text string
node.run_state[:jenkins_private_key] = ENV['PASSWORD'] # Using secure environment variables
In this manner, the cookbook is usable in any environment and is not tied to a single implementation.
- Encrypt the attributes
Credit goes to Jamie Winsor on this one - there is not reason that the only values that can be encrypted are data bags. You can encrypt any string in Ruby, it just takes a little bit more code. You could encrypt the attribute values, decrypt them at runtime for use, and worry-not about persisting the encrypted values on the server.
> encrypt_me "Super secret password" #=> $1$1tKo.EH/$4HvyCFN/9IT.aG5eKTt7H1
# recipe.rb
secret = decrypt_me(node['secret']['value'])
In this example, I've used encrypt_me and decrypt_me, because your encryption algorithms are your choosing.
So, to answer your question(s):
Is there any reason that cookbooks involving the setting of privileged credentials shouldn't enable the use of encrypted data bags for specifying passwords
I just outlined a few
... but some consumers of the cookbook may want to specify the password and not have it be stored as a node attribute.
I think moving the values into the run_context might be more appropriate, since that would not be persisted on the server, but could be loaded in the user's wrapper cookbook easily.
Thanks,
Seth
On Aug 4, 2014, at 8:56 AM, j0hnwarr3n@gmail.com wrote:
In the Chef documentation, database passwords are cited as an example of the
type of confidential information that can be stored in an encrypted data bag
item, yet the two database cookbooks I have looked at--mysql and
postgresql--both use node attributes to set the passwords of their respective
equivalents of a "superuser" account ("root" and "postgres"). Is there any
reason that cookbooks involving the setting of privileged credentials shouldn't
enable the use of encrypted data bags for specifying passwords, so that when
passwords are provided in encrypted data bag items, they are not stored as node
attributes? The reason I ask is that storing them as node attributes would
arguably defeat the purpose of using encrypted data bags to some extent because
the passwords could be retrieved as clear text via the knife node edit command.
I realize that this is done on purpose in the case of postgresql where a
mechanism is required to retrieve randomly generated passwords, but some
consumers of the cookbook may want to specify the password and not have it be
stored as a node attribute.
Any insights on this matter would be appreciated.
Thanks,
John