Knife Secure Bag provides a consistent interface to DataBagItem, EncryptedDataBagItem as well as the custom created SecureDataBagItem while also providing a few extra handy features to help in your DataBag workflows.
SecureDataBagItem, can not only manage your existing DataBagItems and EncryptedDataBagItems, but it also provides you with a DataBag type which enables you to selectively encrypt only some of the fields in your DataBag thus allowing you to be able to search for the remaining fields.
To build and install the plugin add it your Gemfile or run:
gem install secure_data_bag
Defaults for the Knife command may be provided in your knife.rb file.
knife[:secure_data_bag] ||= {}
knife[:secure_data_bag][:encrypted_keys] = %w(
password
ssh_keys
ssh_ids
public_keys
private_keys
keys
secret
)
knife[:secure_data_bag][:secret_file] = "#{local_dir}/secret.pem"
knife[:secure_data_bag][:export_root] = "#{kitchen_dir}/data_bags"
knife[:secure_data_bag][:export_on_upload] = true
knife[:secure_data_bag][:defaults] ||= {}
knife[:secure_data_bag][:defaults][:secrets] ||= {}
knife[:secure_data_bag][:defaults][:secrets][:export_format] = 'plain'
To break this up:
knife[:secure_data_bag][:encrypted_keys] = []
When Knife Secure Bag encrypts a hash with an encryption format of nested, it will recursively walk through the hash from the bottom up and encrypt any key found within this array.
knife[:secure_data_bag][:secret_file]
When encryption is required, the shared secret found at this location will be loaded.
knife[:secure_data_bag][:export_root]
When exporting a data_bag_item, files will be created in below this root directory. Typically this would be the data_bag folder located within your kitchen.
knife[:secure_data_bag][:export_on_upload]
When a data_bag_item is edited using knife secure bag edit
, it may be automatically exported to the export_root.
knife[:secure_data_bag][:defaults][:secrets][:export_format]
The configuration file additionally supports the defaults hash which provides default values for all command line arguments that one might use. Of all of them only the export_format key is likely to be of much use.
metadata = {}
# Define the keys we wish to encrypt
metadata[:encrypted_keys] = %w(encoded)
# Optionally load a specific shared secret. Otherwise, the global
# encrypted\_data\_bag\_secret will be automatically used.
secret_key = SecureDataBagItem.load_key("/path/to/secret")
# Create a hash of data to use as an exampe
raw_data = {
id: "item",
data_bag: "data_bag",
encoded: "my string",
unencoded: "other string"
}
# Instantiate a SecureDataBagItem from a hash
item = SecureDataBagItem.from_hash(data, metadata)
# Or more explicitely
item = SecureDataBagItem.from_hash(data, encrypted_keys: %w(encoded))
# Or load from server
item = SecureDataBagItem.load("data_bag", "item")
# Print the un-encrypted raw data
pp item.raw_data
# Print the un-encrypted `encoded` key
pp item['encoded']
# Print the encrypted hash as a data_bag_item hash
pp item.to_hash
=begin
{
id: "item",
data_bag: "data_bag",
encoded: {
encrypted_data: "encoded",
cipher: aes-256-cbc,
iv: 13453453dkgfefg==
version: 1
}
unencoded: "other string",
}
=end
Print an DataBagItem, EncryptedDataBagItem or SecureDataBagItem, auto-detecting the encryption method used as plain text.
knife secure bag show -F js secrets secret_item
Print an DataBagItem, EncryptedDataBagItem or SecureDataBagItem, auto-detecting the encryption method used as a SecureDataBagItem in encrypted format.
knife secure bag show -F js secrets secret_item --enc-format nested
Edit an EncryptedDataBagItem, preserve it's encryption type, and export a copy to the data_bag folder in your kitchen.
knife secure bag edit secrets secret_item --export
Most of the SubCommands support the following command-line options:
--enc-format [plain,encrypted,nested]
Ensure that, when displaying or uploading the data_bag_item, we forcibly encrypt the data_bag_item using the specified format instead of preserving the existing format.
In this case:
- plain: refers to a DataBagItem
- encrypted: refers to an EnrytpedDataBagItem
- nested: refers to a SecureDataBagItem
--dec-format [plain,encrypted,nested]
Attempt to decrypt the data_bag_item using the given format rather than the auto-detected one. The only real reason to use this is when you wish to specifically select plain as the format so as to not decrypt the item.
--enc-keys key1,key2,key3
Provide a comma delimited list of hash keys which should be encrypted when encrypting the data_bag_item. This list will be concatenated with any key names listed in the configuration file or which were previously encrypted.
--export
Export the data_bag_item to json file in either of export-format or enc-format.
--export-format
Overrides the encryption format only for the export feature.
--export-root
Root directly under which a folder should exist for each data_bag into which to export data_bag_items as json files.
When displaying the content of the data_bag_item, an additional key of _secure_metadata will be added to the output which contains gem specific metadata such as the encryption formats and any encrypted keys found. This key will not be saved with the item, however it may be manipulated to alter the behavior of the edit or export commands.
This command functions just like knife data bag show
and is used to print out the content of either a DataBagItem, EncryptedDataBagItem or SecureDataBagItem.
By default, it will auto-detect the Item type, and print it's unencrypted version to the terminal. This behavior, however, may be altered using the previously mentioned command line options.
This commands functions much like knife secure bag show
, however it is designed to load a data_bag_item from disk as opposed to loading it from Chef server. This may be of use when view the content of an exported encrypted file.
This command functions just like knife data bag edit
and is used to edit either a DataBagItem, EncryptedDataBagItem or a SecureDataBagItem. It supports all of the same options as knife secure bag show
.
This command functions just like knife data bag from file
and is used to upload either a DataBagItem, EncryptedDataBagItem or a SecureDataBagItem. It supports all of the same options as knife secure bag show
.
The gem additionally provides a few Recipe DSL methods which may be useful.
load_secure_item = secure_data_bag_item(
data_bag_name,
data_bag_item,
cache: false
)
load_plain_item = data_bag_item(data_bag_name, data_bag_item)
convert_plain_to_secure = secure_data_bag_item!(load_plain_item)