moonshot 1.1.0.beta1 → 1.1.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2940b0c43a48274eb8368400726fc3269ff6fdf9
4
- data.tar.gz: fb6dfbf21127e8c55533bf848361f81c07f2b0d7
3
+ metadata.gz: 47ebc9ac74a51f7c8b474a1947508d4f32d16e9d
4
+ data.tar.gz: 84c3812ddc48bb7308027d442306a85288be1c94
5
5
  SHA512:
6
- metadata.gz: 146242a237abcccc8229257e0c73310ff539ba1483a57695cc1d6ccbc534778ac015354a9b91fa7ee09e83a8c2e921c3e61946dfd7a5ce0169b04ef005b37376
7
- data.tar.gz: aaf546412e380adc74bc823e7e2a7aef2e1ae31eafb35c2fe284e075b714940eb3d88b7c72dfa53a890f1bf9a62b0fb2108691f52eca510aa205bc1eccf67af2
6
+ metadata.gz: 2bd8244804aa2441c7f95434f68ae5f39c8e0c9fa305d986a66e5477e0285d244a6cb196a77036d22080fe62cf4897b8438f932fba53638fe71120c1b2bc065a
7
+ data.tar.gz: fb7bba6e3ae5e84e2a8f4f9c70953f1578425770fe37ea9ce2a2f2bc7f920757a31f311c7cacc3834488a3355b828871ca22a271fb385620fbb4e0a2c4935a54
@@ -0,0 +1,111 @@
1
+ # This plugin encrypts parameters of the stack using a KMS Key,
2
+ # storing and passing the key used to the stack as a parameter as
3
+ # well. The resources in the stack can then use that KMS Key to
4
+ # decrypt those values.
5
+ #
6
+ # Example:
7
+ #
8
+ # Moonshot.config do |s|
9
+ # # .. mechanism config, etc. ..
10
+ #
11
+ # # The user will be prompted for values for SecretParameter1 and
12
+ # # SecretParameter2, which will then be encrypted by this plugins
13
+ # # pre_create and pre_update hooks.
14
+ # c.plugins << Moonshot::Plugins::EncryptedParameters.new(
15
+ # 'KMSKey1', %w(SecretParameter1 SecretParameter2)
16
+ #
17
+ # # Don't prompt the user for a KMS Key, since the default of 'Auto'
18
+ # # will generate a new key. They can override it with an answer
19
+ # # file or command line parameter if needed.
20
+ # c.parameter_sources['KMSKey1'] = Moonshot::AlwaysUseDefaultSource.new
21
+ # end
22
+ module Moonshot
23
+ class EncryptedParameters
24
+ # @param [String] kms_key_parameter_name
25
+ # The parameter name to store the KMS Key ARN as.
26
+ # @param [Array<String>] parameters
27
+ # Names of parameters to encrypt, if they are not already set.
28
+ def initialize(kms_key_parameter_name, parameters)
29
+ @kms_key_parameter_name = kms_key_parameter_name
30
+ @parameters = parameters
31
+ @delete_key = true
32
+ end
33
+
34
+ def pre_create(res)
35
+ @ilog = res.ilog
36
+
37
+ key_arn = find_or_create_kms_key
38
+ pe = ParameterEncrypter.new(key_arn)
39
+
40
+ @parameters.each do |parameter_name|
41
+ sp = Moonshot.config.parameters[parameter_name]
42
+ raise "No such parameter #{parameter_name}" unless sp
43
+
44
+ @ilog.start_threaded "Handling encrypted parameter #{parameter_name.blue}..." do |s|
45
+ if sp.use_previous?
46
+ # TODO: Remove this and the one below when the upstream race is fixed.
47
+ # See https://github.com/askreet/interactive-logger/issues/7
48
+ sleep 0.05
49
+ s.success "Using previous encrypted value for #{parameter_name.blue}."
50
+ elsif !sp.set? && !sp.default?
51
+ # If the parameter isn't set, we can't encrypt it. Doing
52
+ # nothing means we will give the user a friendly error message
53
+ # about unset parameters when the controller resumes.
54
+ sleep 0.05
55
+ s.failure "No value to encrypt for #{parameter_name.blue}!"
56
+ else
57
+ s.continue "Encrypting new value for parameter #{parameter_name.blue}..."
58
+ Moonshot.config.parameters[sp.name].set(pe.encrypt(sp.value))
59
+ s.success "Encrypted new value for parameter #{parameter_name.blue}!"
60
+ end
61
+ end
62
+ end
63
+ end
64
+ alias pre_update pre_create
65
+
66
+ def post_delete(res)
67
+ key_arn = Moonshot.config.parameters[@kms_key_parameter_name].value
68
+
69
+ res.ilog.start_threaded "Cleaning up KMS Key #{@kms_key_parameter_name.blue}..." do |s|
70
+ if @delete_key
71
+ KmsKey.new(key_arn).delete
72
+ s.success "Deleted KMS Key #{@kms_key_parameter_name.blue}!"
73
+ else
74
+ # TODO: See above.
75
+ sleep 0.05
76
+ s.success "Retained KMS Key #{@kms_key_parameter_name.blue}."
77
+ end
78
+ end
79
+ end
80
+
81
+ def delete_cli_hook(parser)
82
+ parser.on('--retain-kms-key', TrueClass, 'Do not delete the KMS Key for this environment.') do
83
+ @delete_key = false
84
+ end
85
+ end
86
+
87
+ private
88
+
89
+ def find_or_create_kms_key
90
+ key_arn = nil
91
+
92
+ @ilog.start_threaded "Checking for KMS Key #{@kms_key_parameter_name}" do |s|
93
+ if Moonshot.config.parameters.key?(@kms_key_parameter_name)
94
+ if 'Auto' == Moonshot.config.parameters[@kms_key_parameter_name].value
95
+ s.continue "Auto-generating KMS Key for #{@kms_key_parameter_name.blue}... "
96
+ key_arn = KmsKey.create.arn
97
+ Moonshot.config.parameters[@kms_key_parameter_name].set(key_arn)
98
+ s.success "Created a new KMS Key for #{@kms_key_parameter_name.blue}!"
99
+ else
100
+ key_arn = KmsKey.new(Moonshot.config.parameters[@kms_key_parameter_name].value).arn
101
+ s.success "Using existing KMS Key for #{@kms_key_parameter_name.blue}!"
102
+ end
103
+ end
104
+ end
105
+
106
+ raise "No such Stack Parameter #{@kms_key_parameter_name}!" unless key_arn
107
+
108
+ key_arn
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,22 @@
1
+ class EncryptedParameters
2
+ # Class that manages KMS keys in AWS.
3
+ class KmsKey
4
+ attr_reader :arn
5
+
6
+ def initialize(arn)
7
+ @arn = arn
8
+ @kms_client = Aws::KMS::Client.new
9
+ end
10
+
11
+ def self.create
12
+ resp = Aws::KMS::Client.new.create_key
13
+ arn = resp.key_metadata.arn
14
+
15
+ new(arn)
16
+ end
17
+
18
+ def delete
19
+ @kms_client.schedule_key_deletion(key_id: @arn, pending_window_in_days: 7)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,23 @@
1
+ require 'base64'
2
+
3
+ class EncryptedParameters
4
+ # Class that can encrypt and decrypt parameters using KMS.
5
+ class ParameterEncrypter
6
+ # @param [String] key_arn The ARN for the KMS key.
7
+ def initialize(key_arn)
8
+ @kms_client = Aws::KMS::Client.new
9
+ @key_arn = key_arn
10
+ end
11
+
12
+ # Encrypt and base64 encode the parameter value.
13
+ #
14
+ # @param [String] param_value The parameter to encrypt.
15
+ # @return [String] base64 encoded encrypted ciphertext.
16
+ def encrypt(param_value)
17
+ resp = @kms_client.encrypt(key_id: @key_arn, plaintext: param_value)
18
+
19
+ # Use strict here to avoid newlines which cause issues with parameters.
20
+ Base64.strict_encode64(resp.ciphertext_blob)
21
+ end
22
+ end
23
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: moonshot
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0.beta1
4
+ version: 1.1.0.beta2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cloud Engineering <engineering@acquia.com>
@@ -317,6 +317,9 @@ files:
317
317
  - lib/moonshot/unicode_table.rb
318
318
  - lib/moonshot/yaml_stack_template.rb
319
319
  - lib/plugins/backup.rb
320
+ - lib/plugins/encrypted_parameters.rb
321
+ - lib/plugins/encrypted_parameters/kms_key.rb
322
+ - lib/plugins/encrypted_parameters/parameter_encrypter.rb
320
323
  homepage: https://github.com/acquia/moonshot
321
324
  licenses:
322
325
  - Apache-2.0