secure_data_bag 2.2.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,3 @@
1
-
2
1
  module SecureDataBag
3
- VERSION = "2.2.0"
2
+ VERSION = '3.0.0'.freeze
4
3
  end
5
-
@@ -4,23 +4,24 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'secure_data_bag/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "secure_data_bag"
7
+ spec.name = 'secure_data_bag'
8
8
  spec.version = SecureDataBag::VERSION
9
- spec.authors = ["Jonathan Serafini"]
10
- spec.email = ["jonathan@lightspeedretail.com"]
11
- spec.summary = "Per-field data bag item encryption"
12
- spec.description = "Provides a mechanism to partially encrypt data bag items and therefore ensure that they are searchable"
13
- spec.license = "MIT"
14
- spec.homepage =
15
- "https://github.com/JonathanSerafini/chef-secure_data_bag"
9
+ spec.authors = ['Jonathan Serafini']
10
+ spec.email = ['jonathan@lightspeedretail.com']
11
+ spec.summary = 'Mechanism to partially encryot data bag items'
12
+ spec.description = IO.read(File.join(File.dirname(__FILE__), 'README.md'))
13
+ spec.license = 'MIT'
14
+ spec.homepage =
15
+ 'https://github.com/JonathanSerafini/chef-secure_data_bag'
16
16
  spec.files = `git ls-files -z`.split("\x0")
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
19
+ spec.require_paths = ['lib']
20
20
 
21
- spec.add_dependency "chef"
21
+ spec.add_dependency 'chef'
22
22
 
23
- spec.add_development_dependency "bundler", "~> 1.6"
24
- spec.add_development_dependency "rake"
25
- spec.add_development_dependency "rspec"
23
+ spec.add_development_dependency 'bundler', '~> 1.6'
24
+ spec.add_development_dependency 'rake'
25
+ spec.add_development_dependency 'rspec'
26
+ spec.add_development_dependency 'cookstyle'
26
27
  end
@@ -4,14 +4,14 @@ require 'chef/data_bag_item'
4
4
  require 'chef/encrypted_data_bag_item'
5
5
 
6
6
  describe SecureDataBag::Item do
7
- let(:key) { "password" }
8
- let(:secret) { "data/secret.pem" }
9
- let(:fields) { ["encoded"] }
7
+ let(:key) { 'password' }
8
+ let(:secret) { 'data/secret.pem' }
9
+ let(:fields) { ['encoded'] }
10
10
 
11
- let(:simple_data) { { "id"=>"test", decoded:"decoded", encoded:"encoded" } }
12
- let(:nested_data) { simple_data.merge({ nested:simple_data }) }
11
+ let(:simple_data) { { 'id' => 'test', decoded: 'decoded', encoded: 'encoded' } }
12
+ let(:nested_data) { simple_data.merge(nested: simple_data) }
13
13
 
14
- let(:item) { SecureDataBag::Item.new(key:key, fields:fields) }
14
+ let(:item) { SecureDataBag::Item.new(key: key, fields: fields) }
15
15
 
16
16
  let(:dbag_item) do
17
17
  dbag_item = Chef::DataBagItem.new
@@ -31,29 +31,28 @@ describe SecureDataBag::Item do
31
31
  nested_item
32
32
  end
33
33
 
34
- it "encodes simple data" do
34
+ it 'encodes simple data' do
35
35
  dbag = simple_item
36
36
  data = dbag.encoded_data
37
- expect(data[:decoded]).to eq("decoded")
38
- expect(data[:encoded]).not_to eq("encoded")
37
+ expect(data[:decoded]).to eq('decoded')
38
+ expect(data[:encoded]).not_to eq('encoded')
39
39
  expect(data[:encoded][:encrypted_data]).not_to eq(nil)
40
40
  end
41
41
 
42
- it "encodes nested data" do
42
+ it 'encodes nested data' do
43
43
  dbag = nested_item
44
44
  data = dbag.encoded_data
45
- expect(data[:nested][:decoded]).to eq("decoded")
46
- expect(data[:nested][:encoded]).not_to eq("encoded")
45
+ expect(data[:nested][:decoded]).to eq('decoded')
46
+ expect(data[:nested][:encoded]).not_to eq('encoded')
47
47
  expect(data[:nested][:encoded][:encrypted_data]).not_to eq(nil)
48
48
  end
49
49
 
50
- it "decodes encrypted_data_bag_item" do
50
+ it 'decodes encrypted_data_bag_item' do
51
51
  edbag = Chef::EncryptedDataBagItem.encrypt_data_bag_item(dbag_item, key)
52
52
  dbag = item
53
53
  dbag.raw_data = edbag
54
54
  data = dbag.raw_data
55
- expect(data[:decoded]).to eq("decoded")
56
- expect(data[:encoded]).to eq("encoded")
55
+ expect(data[:decoded]).to eq('decoded')
56
+ expect(data[:encoded]).to eq('encoded')
57
57
  end
58
58
  end
59
-
@@ -14,4 +14,3 @@ RSpec.configure do |config|
14
14
  mocks.verify_partial_doubles = true
15
15
  end
16
16
  end
17
-
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: secure_data_bag
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Serafini
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-26 00:00:00.000000000 Z
11
+ date: 2016-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chef
@@ -66,8 +66,103 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
- description: Provides a mechanism to partially encrypt data bag items and therefore
70
- ensure that they are searchable
69
+ - !ruby/object:Gem::Dependency
70
+ name: cookstyle
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: "# SecureDataBag / Knife Secure Bag\n\nKnife Secure Bag provides a consistent
84
+ interface to DataBagItem, EncryptedDataBagItem as well as the custom created SecureDataBagItem
85
+ while also providing a few extra handy features to help in your DataBag workflows.
86
+ \n\nSecureDataBagItem, can not only manage your existing DataBagItems and EncryptedDataBagItems,
87
+ but it also provides you with a DataBag type which enables you to selectively encrypt
88
+ only some of the fields in your DataBag thus allowing you to be able to search for
89
+ the remaining fields. \n\n## Installation\n\nTo build and install the plugin add
90
+ it your Gemfile or run: \n\n```shell\ngem install secure_data_bag\n```\n\n## Configuration\n\n####
91
+ Knife Secure Bag\n\nDefaults for the Knife command may be provided in your _knife.rb_
92
+ file.\n\n```ruby\nknife[:secure_data_bag][:encrypted_keys] = %w(\n password\n ssh_keys\n
93
+ \ ssh_ids\n public_keys\n private_keys\n keys\n secret\n)\nknife[:secure_data_bag][:secret_file]
94
+ = \"#{local_dir}/secret.pem\"\nknife[:secure_data_bag][:export_root] = \"#{kitchen_dir}/data_bags\"\nknife[:secure_data_bag][:export_on_upload]
95
+ = true\nknife[:secure_data_bag][:defaults][:secrets][:export_format] = 'plain'\n```\n\nTo
96
+ break this up:\n\n`knife[:secure_data_bag][:encrypted_keys] = []`\n\nWhen Knife
97
+ Secure Bag encrypts a hash with an _encryption format_ of *nested*, it will recursively
98
+ walk through the hash from the bottom up and encrypt any key found within this array.\n\n`knife[:secure_data_bag][:secret_file]`\n\nWhen
99
+ encryption is required, the shared secret found at this location will be loaded.
100
+ \n\n`knife[:secure_data_bag][:export_root]`\n\nWhen exporting a data\\_bag\\_item,
101
+ files will be created in below this root directory. Typically this would be the
102
+ data\\_bag folder located within your kitchen.\n\n`knife[:secure_data_bag][:export_on_upload]`\n\nWhen
103
+ a data\\_bag\\_item is edited using `knife secure bag edit`, it may be automatically
104
+ exported to the _export\\_root_.\n\n`knife[:secure_data_bag][:defaults][:secrets][:export_format]`\n\nThe
105
+ configuration file additionally supports the _defaults_ hash which provides default
106
+ values for all _command line arguments_ that one might use. Of all of them only
107
+ the _export\\_format_ key is likely to be of much use.\n\n## Examples\n\n#### Chef
108
+ cookbook recipe\n\n```ruby\nmetadata = {}\n\n# Define the keys we wish to encrypt\nmetadata[:encrypted_keys]
109
+ = %w(encoded)\n\n# Optionally load a specific shared secret. Otherwise, the global
110
+ \n# encrypted\\_data\\_bag\\_secret will be automatically used.\nsecret_key = SecureDataBagItem.load_key(\"/path/to/secret\")\n\n#
111
+ Create a hash of data to use as an exampe\nraw_data = {\n\tid: \"item\", \n data_bag:
112
+ \"data_bag\",\n\tencoded: \"my string\", \n\tunencoded: \"other string\"\n}\n\n#
113
+ Instantiate a SecureDataBagItem from a hash\nitem = SecureDataBagItem.from_hash(data,
114
+ metadata)\n\n# Or more explicitely\nitem = SecureDataBagItem.from_hash(data, encrypted_keys:
115
+ %w(encoded))\n\n# Or load from server\nitem = SecureDataBagItem.load(\"data_bag\",
116
+ \"item\")\n\n# Print the un-encrypted raw data\npp item.raw_data\n\n# Print the
117
+ un-encrypted `encoded` key\npp item['encoded']\n\n# Print the encrypted hash as
118
+ a data_bag_item hash\npp item.to_hash\n\n=begin\n{ \n id: \"item\", \n
119
+ \ data_bag: \"data_bag\",\n encoded: {\n encrypted_data: \"encoded\",\n
120
+ \ cipher: aes-256-cbc,\n iv: 13453453dkgfefg==\n version: 1\n }\n unencoded:
121
+ \ \"other string\",\n}\n=end\n```\n\n## Usage\n\n#### Knife commands\n\nPrint an
122
+ DataBagItem, EncryptedDataBagItem or SecureDataBagItem, auto-detecting the encryption
123
+ method used as plain text.\n\n```shell\nknife secure bag show -F js secrets secret_item\n```\n\nPrint
124
+ an DataBagItem, EncryptedDataBagItem or SecureDataBagItem, auto-detecting the encryption
125
+ method used as a SecureDataBagItem in encrypted format.\n\n```shell\nknife secure
126
+ bag show -F js secrets secret_item --enc-format nested\n```\n\nEdit an EncryptedDataBagItem,
127
+ preserve it's encryption type, and export a copy to the _data\\_bag_ folder in your
128
+ kitchen.\n\n```shell\nknife secure bag edit secrets secret_item --export\n```\n\n##
129
+ Knife SubCommands\n\nMost of the SubCommands support the following command-line
130
+ options:\n\n`--enc-format [plain,encrypted,nested]`\n\nEnsure that, when displaying
131
+ or uploading the data\\_bag\\_item, we forcibly encrypt the data\\_bag\\_item using
132
+ the specified format instead of preserving the existing format. \n\nIn this case:
133
+ \n- plain: refers to a DataBagItem\n- encrypted: refers to an EnrytpedDataBagItem\n-
134
+ nested: refers to a SecureDataBagItem\n\n`--dec-format [plain,encrypted,nested]`\n\nAttempt
135
+ to decrypt the data\\_bag\\_item using the given format rather than the auto-detected
136
+ one. The only real reason to use this is when you wish to specifically select _plain_
137
+ as the format so as to not decrypt the item.\n\n`--enc-keys key1,key2,key3`\n\nProvide
138
+ a comma delimited list of hash keys which should be encrypted when encrypting the
139
+ data\\_bag\\_item. This list will be concatenated with any key names listed in the
140
+ configuration file or which were previously encrypted. \n\n`--export`\n\nExport
141
+ the data\\_bag\\_item to json file in either of _export-format_ or _enc-format_.\n\n`--export-format`\n\nOverrides
142
+ the encryption format only for the _export_ feature.\n\n`--export-root`\n\nRoot
143
+ directly under which a folder should exist for each _data_bag_ into which to export
144
+ _data_bag_items_ as json files.\n\nWhen displaying the content of the _data\\_bag\\_item_,
145
+ an additional key of *_secure_metadata* will be added to the output which contains
146
+ gem specific metadata such as the encryption formats and any encrypted keys found.
147
+ This key will _not_ be saved with the item, however it may be manipulated to alter
148
+ the behavior of the _edit_ or _export_ commands.\n\n#### knife secure bag show DATA_BAG
149
+ ITEM\n\nThis command functions just like `knife data bag show` and is used to print
150
+ out the content of either a DataBagItem, EncryptedDataBagItem or SecureDataBagItem.\n\nBy
151
+ default, it will auto-detect the Item type, and print it's unencrypted version to
152
+ the terminal. This behavior, however, may be altered using the previously mentioned
153
+ command line options.\n\n#### knife secure bag open PATH\n\nThis commands functions
154
+ much like `knife secure bag show`, however it is designed to load a _data\\_bag\\_item_
155
+ from disk as opposed to loading it from Chef server. This may be of use when view
156
+ the content of an exported encrypted file.\n\n#### knife secure bag edit DATA_BAG
157
+ DATA_BAG_ITEM\n\nThis command functions just like `knife data bag edit` and is used
158
+ to edit either a DataBagItem, EncryptedDataBagItem or a SecureDataBagItem. It supports
159
+ all of the same options as `knife secure bag show`. \n\n#### knife secure bag from
160
+ file DATA_BAG PATH\n\nThis command functions just like `knife data bag from file`
161
+ and is used to upload either a DataBagItem, EncryptedDataBagItem or a SecureDataBagItem.
162
+ It supports all of the same options as `knife secure bag show`. \n\n## Recipe DSL\n\nThe
163
+ gem additionally provides a few Recipe DSL methods which may be useful.\n\n```ruby\nload_secure_item
164
+ = secure_data_bag_item(\n data_bag_name, \n data_bag_item, \n cache: false\n)\n\nload_plain_item
165
+ = data_bag_item(data_bag_name, data_bag_item)\nconvert_plain_to_secure = secure_data_bag_item!(load_plain_item)\n```\n\n"
71
166
  email:
72
167
  - jonathan@lightspeedretail.com
73
168
  executables: []
@@ -76,18 +171,28 @@ extra_rdoc_files: []
76
171
  files:
77
172
  - ".gitignore"
78
173
  - ".rspec"
174
+ - CHANGELOG.md
79
175
  - Gemfile
80
176
  - LICENSE.txt
81
177
  - README.md
82
178
  - Rakefile
83
179
  - lib/chef/config.rb
84
180
  - lib/chef/dsl/data_query.rb
85
- - lib/chef/knife/secure_bag_base.rb
86
181
  - lib/chef/knife/secure_bag_edit.rb
87
182
  - lib/chef/knife/secure_bag_from_file.rb
183
+ - lib/chef/knife/secure_bag_open.rb
88
184
  - lib/chef/knife/secure_bag_show.rb
185
+ - lib/chef/knife/secure_data_bag/base_mixin.rb
186
+ - lib/chef/knife/secure_data_bag/defaults_mixin.rb
187
+ - lib/chef/knife/secure_data_bag/export_mixin.rb
188
+ - lib/chef/knife/secure_data_bag/secrets_mixin.rb
89
189
  - lib/secure_data_bag.rb
190
+ - lib/secure_data_bag/check_encrypted.rb
191
+ - lib/secure_data_bag/constants.rb
192
+ - lib/secure_data_bag/decryptor.rb
90
193
  - lib/secure_data_bag/dsl/data_query.rb
194
+ - lib/secure_data_bag/encryptor.rb
195
+ - lib/secure_data_bag/exceptions.rb
91
196
  - lib/secure_data_bag/item.rb
92
197
  - lib/secure_data_bag/version.rb
93
198
  - secure_data_bag.gemspec
@@ -113,10 +218,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
218
  version: '0'
114
219
  requirements: []
115
220
  rubyforge_project:
116
- rubygems_version: 2.4.5.1
221
+ rubygems_version: 2.2.3
117
222
  signing_key:
118
223
  specification_version: 4
119
- summary: Per-field data bag item encryption
224
+ summary: Mechanism to partially encryot data bag items
120
225
  test_files:
121
226
  - spec/item_spec.rb
122
227
  - spec/spec_helper.rb
@@ -1,74 +0,0 @@
1
-
2
- require 'chef/knife'
3
-
4
- class Chef
5
- class Knife
6
- module SecureBagBase
7
- def self.included(includer)
8
- includer.class_eval do
9
- deps do
10
- require 'secure_data_bag'
11
- end
12
-
13
- option :secret,
14
- short: "-s SECRET",
15
- long: "--secret",
16
- description: "The secret key to use to encrypt data bag item values"
17
-
18
- option :secret_file,
19
- long: "--secret-file SECRET_FILE",
20
- description: "A file containing a secret key to use to encrypt data bag item values"
21
-
22
- option :encoded_fields,
23
- long: "--encoded-fields FIELD1,FIELD2,FIELD3",
24
- description: "List of attribute keys for which to encode values",
25
- proc: Proc.new { |s| s.split(',') }
26
- end
27
- end
28
-
29
- def encoded_fields
30
- config[:encoded_fields] ||
31
- Chef::Config[:knife][:secure_data_bag][:fields]
32
- end
33
-
34
- def secret_file
35
- config[:secret_file] ||
36
- SecureDataBag::Item.secret_path
37
- end
38
-
39
- def secret
40
- @secret ||= read_secret
41
- end
42
-
43
- def use_encryption
44
- true
45
- end
46
-
47
- def read_secret
48
- if config[:secret] then config[:secret]
49
- else SecureDataBag::Item.load_secret(secret_file)
50
- end
51
- end
52
-
53
- def require_secret
54
- if not secret
55
- show_usage
56
- ui.fatal("A secret or secret_file must be specified")
57
- exit 1
58
- end
59
- end
60
-
61
- def data_for_create(hash={})
62
- hash[:id] = @data_bag_item_name
63
- hash
64
- end
65
-
66
- def data_for_save(hash)
67
- @encoded_fields = hash.delete(:_encoded_fields)
68
- hash
69
- end
70
-
71
- end
72
- end
73
- end
74
-