kms_rails 0.0.10 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +14 -13
- data/README.md +23 -5
- data/kms_rails.gemspec +21 -22
- data/lib/kms_rails/configuration.rb +3 -2
- data/lib/kms_rails/core.rb +12 -12
- data/lib/kms_rails/kms_client_mock.rb +23 -27
- data/lib/kms_rails/version.rb +1 -1
- metadata +18 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b373095acd772fa6c6b92d73fbb0aef0858fa3eed9d19cff7c055dbcadf3e0cb
|
4
|
+
data.tar.gz: 8a02cf1e4cb494e0ba57a6e9d444404cbe621de7fb1f66ef0b3309e46949c0b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c57077d895db30059c1516a0ab4d31c4fc11a6b1f5e35815aab266a916d8cc5f4a6f3d0c0791bf02cc61f25b78704924de04e23798b3e45e7ab0b81af83c10a4
|
7
|
+
data.tar.gz: 075f72d9912180b13a255857219ff7b2be6ad11db42512e654178c9897e16a6e51fb3e65d8a54351ccbce20c58823730f86d845582a0fa919a5b5e4262afe83f
|
data/.travis.yml
CHANGED
@@ -1,17 +1,18 @@
|
|
1
|
+
env:
|
2
|
+
global:
|
3
|
+
- CC_TEST_REPORTER_ID=156fab7dad33afa6dd4b24ab5721a01e5bbb41c3f07c380195695102b7363e0a
|
4
|
+
|
1
5
|
language: ruby
|
2
6
|
rvm:
|
3
|
-
- 2.1
|
4
|
-
- 2.2
|
5
|
-
- 2.3
|
6
|
-
- 2.4
|
7
7
|
- 2.5
|
8
|
-
|
9
|
-
|
10
|
-
code_climate:
|
11
|
-
repo_token: 156fab7dad33afa6dd4b24ab5721a01e5bbb41c3f07c380195695102b7363e0a
|
8
|
+
- 2.6
|
9
|
+
- 2.7
|
12
10
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
11
|
+
before_script:
|
12
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
13
|
+
- chmod +x ./cc-test-reporter
|
14
|
+
- ./cc-test-reporter before-build
|
15
|
+
script:
|
16
|
+
- bundle exec rspec spec
|
17
|
+
after_script:
|
18
|
+
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
data/README.md
CHANGED
@@ -115,14 +115,14 @@ Aws.config[:region] = 'us-east-1'
|
|
115
115
|
|
116
116
|
or by using the documented AWS environmental variables.
|
117
117
|
|
118
|
-
##
|
118
|
+
## Custom KMS client
|
119
119
|
|
120
|
-
A basic fake implementation of `Aws::KMS::Client` has been written, allowing kms_rails functionality to be used in test environments without making any web requests. The fake implementation emulates the functionality of the two API calls kms_rails issues to AWS and performs fake encryption (the key is 'encrypted' by reversing it).
|
120
|
+
A basic fake implementation of `Aws::KMS::Client` has been written (`KmsRails::KmsClientMock`), allowing kms_rails functionality to be used in test environments without making any web requests. The fake implementation emulates the functionality of the two API calls kms_rails issues to AWS and performs fake encryption (the key is 'encrypted' by reversing it).
|
121
121
|
|
122
|
-
You can enable it in your Rails initializers with the following
|
122
|
+
You can enable it (or set any custom KMS client with alternate config) in your Rails initializers with the following
|
123
123
|
```ruby
|
124
124
|
KmsRails.configure do |config|
|
125
|
-
config.
|
125
|
+
config.kms_client = KmsRails::KmsClientMock.new
|
126
126
|
end
|
127
127
|
```
|
128
128
|
|
@@ -142,10 +142,28 @@ Will resolve 'my-key-alias' to 'alias/production/my-key-alias' in the production
|
|
142
142
|
|
143
143
|
Directly specifying a key_id as a UUID or with the `alias/` prefix explicitly declared will prevent this behaviour from occurring.
|
144
144
|
|
145
|
+
## ARN prefixes
|
146
|
+
|
147
|
+
You can use the `arn_prefix` configuration option to specify that the keys you're referencing are located in a different AWS account or region than the default. For example;
|
148
|
+
|
149
|
+
```ruby
|
150
|
+
KmsRails.configure do |config|
|
151
|
+
config.arn_prefix = 'arn:aws:kms:ap-southeast-1:11111111111:'
|
152
|
+
end
|
153
|
+
|
154
|
+
kms_attr :my_attribute, key_id: 'my-key-alias'
|
155
|
+
```
|
156
|
+
|
157
|
+
Will resolve 'my-key-alias' to 'arn:aws:kms:ap-southeast-1:11111111111:alias/my-key-alias', which may be a key in a different region or AWS account.
|
158
|
+
|
159
|
+
This works for aliases and UUID keys, but Proc based key_ids will not have the ARN prefixed.
|
160
|
+
|
161
|
+
You can use this in combination with alias prefixes. A prefix like 'foo/' would result in a final key of 'arn:aws:kms:ap-southeast-1:11111111111:alias/foo/my-key-alias'.
|
162
|
+
|
145
163
|
## Other stuff
|
146
164
|
|
147
165
|
### Notes
|
148
|
-
This gem has been developed against Ruby 2.3.1, Rails 4.2, and AWS SDK
|
166
|
+
This gem has been developed against Ruby 2.3.1, Rails 4.2, and AWS SDK v3. Credit where credit is due, strongbox by spikex was used as an inspiration and guide when creating this. https://github.com/spikex/strongbox
|
149
167
|
|
150
168
|
### Disclaimer
|
151
169
|
No claims are made about enhanced security when using this gem.
|
data/kms_rails.gemspec
CHANGED
@@ -4,35 +4,34 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'kms_rails/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = 'kms_rails'
|
8
8
|
spec.version = KmsRails::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
9
|
+
spec.authors = ['Ash Tyndall', 'Justin Ouellette']
|
10
|
+
spec.email = ['ash@appbot.co']
|
11
11
|
|
12
12
|
spec.summary = %q{AWS KMS encryption for ActiveRecord & ActiveJob.}
|
13
13
|
spec.description = %q{Quickly add KMS encryption and decryption to your ActiveRecord model attributes and ActiveJob parameters. Improves upon kms_attrs with ActiveJob support, more efficient binary serialization and a test suite.}
|
14
|
-
spec.homepage =
|
15
|
-
spec.license =
|
14
|
+
spec.homepage = 'https://github.com/appbot/kms_rails'
|
15
|
+
spec.license = 'GPLv3'
|
16
16
|
|
17
17
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
-
spec.bindir =
|
18
|
+
spec.bindir = 'exe'
|
19
19
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
-
spec.require_paths = [
|
21
|
-
spec.required_ruby_version = '>= 2.
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
spec.required_ruby_version = '>= 2.5'
|
22
22
|
|
23
|
-
spec.add_runtime_dependency
|
24
|
-
spec.add_runtime_dependency
|
25
|
-
spec.add_runtime_dependency
|
26
|
-
spec.add_runtime_dependency
|
23
|
+
spec.add_runtime_dependency 'activerecord', '>= 4'
|
24
|
+
spec.add_runtime_dependency 'activejob', '>= 4'
|
25
|
+
spec.add_runtime_dependency 'aws-sdk-kms', '~> 1'
|
26
|
+
spec.add_runtime_dependency 'msgpack'
|
27
27
|
|
28
|
-
spec.add_development_dependency
|
29
|
-
spec.add_development_dependency
|
30
|
-
spec.add_development_dependency
|
31
|
-
spec.add_development_dependency
|
32
|
-
spec.add_development_dependency
|
33
|
-
spec.add_development_dependency
|
34
|
-
spec.add_development_dependency
|
35
|
-
spec.add_development_dependency
|
36
|
-
spec.add_development_dependency
|
37
|
-
spec.add_development_dependency "database_cleaner"
|
28
|
+
spec.add_development_dependency 'bundler'
|
29
|
+
spec.add_development_dependency 'rake', '>= 12.3.3'
|
30
|
+
spec.add_development_dependency 'rspec'
|
31
|
+
spec.add_development_dependency 'rspec-mocks'
|
32
|
+
spec.add_development_dependency 'simplecov'
|
33
|
+
spec.add_development_dependency 'with_model'
|
34
|
+
spec.add_development_dependency 'byebug'
|
35
|
+
spec.add_development_dependency 'sqlite3'
|
36
|
+
spec.add_development_dependency 'database_cleaner'
|
38
37
|
end
|
@@ -3,11 +3,12 @@ module KmsRails
|
|
3
3
|
attr_writer :configuration
|
4
4
|
|
5
5
|
class Configuration
|
6
|
-
attr_accessor :
|
6
|
+
attr_accessor :kms_client, :alias_prefix, :arn_prefix
|
7
7
|
|
8
8
|
def initialize
|
9
|
-
@
|
9
|
+
@kms_client = nil
|
10
10
|
@alias_prefix = ''
|
11
|
+
@arn_prefix = ''
|
11
12
|
end
|
12
13
|
end
|
13
14
|
|
data/lib/kms_rails/core.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'base64'
|
2
2
|
require 'openssl'
|
3
3
|
require 'msgpack'
|
4
|
-
require 'aws-sdk'
|
4
|
+
require 'aws-sdk-kms'
|
5
5
|
require 'kms_rails/configuration'
|
6
6
|
|
7
7
|
module KmsRails
|
@@ -41,15 +41,15 @@ module KmsRails
|
|
41
41
|
return nil if data_obj.nil?
|
42
42
|
|
43
43
|
decrypted = decrypt_attr(
|
44
|
-
data_obj['blob'],
|
44
|
+
data_obj['blob'],
|
45
45
|
aws_decrypt_key(data_obj['key']),
|
46
46
|
data_obj['iv']
|
47
47
|
)
|
48
|
-
|
48
|
+
|
49
49
|
decrypted = MessagePack.unpack(decrypted) if @msgpack
|
50
50
|
decrypted
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
def decrypt64(data_obj)
|
54
54
|
return nil if data_obj.nil?
|
55
55
|
decrypt( self.class.from64(data_obj) )
|
@@ -61,9 +61,9 @@ module KmsRails
|
|
61
61
|
@base_key_id.call
|
62
62
|
when String
|
63
63
|
if @base_key_id =~ /\A\w{8}-\w{4}-\w{4}-\w{4}-\w{12}\z/ || @base_key_id.start_with?('alias/') # if UUID or direct alias
|
64
|
-
@base_key_id
|
64
|
+
KmsRails.configuration.arn_prefix + @base_key_id
|
65
65
|
else
|
66
|
-
'alias/' + KmsRails.configuration.alias_prefix + @base_key_id
|
66
|
+
KmsRails.configuration.arn_prefix + 'alias/' + KmsRails.configuration.alias_prefix + @base_key_id
|
67
67
|
end
|
68
68
|
else
|
69
69
|
raise RuntimeError, 'Only Proc and String arguments are supported'
|
@@ -85,7 +85,7 @@ module KmsRails
|
|
85
85
|
data_obj.map { |k,v| [k, Base64.strict_decode64(v)] }.to_h
|
86
86
|
end
|
87
87
|
|
88
|
-
private
|
88
|
+
private
|
89
89
|
|
90
90
|
def apply_context(args, key, value)
|
91
91
|
if key && value
|
@@ -123,17 +123,17 @@ module KmsRails
|
|
123
123
|
|
124
124
|
def aws_decrypt_key(key)
|
125
125
|
args = {ciphertext_blob: key}
|
126
|
-
aws_kms.decrypt(apply_context(args, @context_key, @context_value)).plaintext
|
126
|
+
aws_kms.decrypt(**apply_context(args, @context_key, @context_value)).plaintext
|
127
127
|
end
|
128
128
|
|
129
129
|
def aws_kms
|
130
|
-
|
131
|
-
|
130
|
+
KmsRails.configuration.kms_client ||
|
131
|
+
(@aws_kms ||= Aws::KMS::Client.new)
|
132
132
|
end
|
133
133
|
|
134
134
|
def aws_generate_data_key(key_id)
|
135
135
|
args = {key_id: key_id, key_spec: 'AES_256'}
|
136
|
-
aws_kms.generate_data_key(apply_context(args, @context_key, @context_value))
|
136
|
+
aws_kms.generate_data_key(**apply_context(args, @context_key, @context_value))
|
137
137
|
end
|
138
138
|
end
|
139
|
-
end
|
139
|
+
end
|
@@ -1,38 +1,34 @@
|
|
1
|
-
require 'aws-sdk'
|
1
|
+
require 'aws-sdk-kms'
|
2
2
|
require 'msgpack'
|
3
3
|
|
4
4
|
module KmsRails
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
def generate_data_key(key_id:, key_spec:, encryption_context: nil)
|
9
|
-
raise RuntimeError, 'Unsupported key_spec in test mode' unless key_spec == 'AES_256'
|
5
|
+
class KmsClientMock
|
6
|
+
def generate_data_key(key_id:, key_spec:, encryption_context: nil)
|
7
|
+
raise RuntimeError, 'Unsupported key_spec in test mode' unless key_spec == 'AES_256'
|
10
8
|
|
11
|
-
|
9
|
+
plaintext = SecureRandom.random_bytes(256/8)
|
12
10
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
11
|
+
::Aws::KMS::Types::GenerateDataKeyResponse.new(
|
12
|
+
key_id: key_id,
|
13
|
+
plaintext: plaintext,
|
14
|
+
ciphertext_blob: [key_id, encryption_context, plaintext].to_msgpack.reverse,
|
15
|
+
)
|
16
|
+
end
|
19
17
|
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
def decrypt(ciphertext_blob:, encryption_context: nil)
|
19
|
+
key_id, decoded_context, plaintext = MessagePack.unpack(ciphertext_blob.reverse)
|
20
|
+
raise ::Aws::KMS::Errors::InvalidCiphertextException.new(nil, nil) unless decoded_context == encryption_context
|
23
21
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
22
|
+
::Aws::KMS::Types::DecryptResponse.new(
|
23
|
+
key_id: key_id,
|
24
|
+
plaintext: plaintext,
|
25
|
+
)
|
26
|
+
rescue MessagePack::MalformedFormatError
|
27
|
+
raise ::Aws::KMS::Errors::InvalidCiphertextException.new(nil, nil)
|
28
|
+
end
|
31
29
|
|
32
|
-
|
33
|
-
|
34
|
-
end
|
35
|
-
end
|
30
|
+
def inspect
|
31
|
+
"#<Aws::KMS::Client (mocked)>"
|
36
32
|
end
|
37
33
|
end
|
38
34
|
end
|
data/lib/kms_rails/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kms_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ash Tyndall
|
8
8
|
- Justin Ouellette
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-08-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -40,19 +40,19 @@ dependencies:
|
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: '4'
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
|
-
name: aws-sdk
|
43
|
+
name: aws-sdk-kms
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
46
|
- - "~>"
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version: '
|
48
|
+
version: '1'
|
49
49
|
type: :runtime
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
53
|
- - "~>"
|
54
54
|
- !ruby/object:Gem::Version
|
55
|
-
version: '
|
55
|
+
version: '1'
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
57
|
name: msgpack
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -71,30 +71,30 @@ dependencies:
|
|
71
71
|
name: bundler
|
72
72
|
requirement: !ruby/object:Gem::Requirement
|
73
73
|
requirements:
|
74
|
-
- - "
|
74
|
+
- - ">="
|
75
75
|
- !ruby/object:Gem::Version
|
76
|
-
version: '
|
76
|
+
version: '0'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
79
|
version_requirements: !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
|
-
- - "
|
81
|
+
- - ">="
|
82
82
|
- !ruby/object:Gem::Version
|
83
|
-
version: '
|
83
|
+
version: '0'
|
84
84
|
- !ruby/object:Gem::Dependency
|
85
85
|
name: rake
|
86
86
|
requirement: !ruby/object:Gem::Requirement
|
87
87
|
requirements:
|
88
|
-
- - "
|
88
|
+
- - ">="
|
89
89
|
- !ruby/object:Gem::Version
|
90
|
-
version:
|
90
|
+
version: 12.3.3
|
91
91
|
type: :development
|
92
92
|
prerelease: false
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
|
-
- - "
|
95
|
+
- - ">="
|
96
96
|
- !ruby/object:Gem::Version
|
97
|
-
version:
|
97
|
+
version: 12.3.3
|
98
98
|
- !ruby/object:Gem::Dependency
|
99
99
|
name: rspec
|
100
100
|
requirement: !ruby/object:Gem::Requirement
|
@@ -137,20 +137,6 @@ dependencies:
|
|
137
137
|
- - ">="
|
138
138
|
- !ruby/object:Gem::Version
|
139
139
|
version: '0'
|
140
|
-
- !ruby/object:Gem::Dependency
|
141
|
-
name: codeclimate-test-reporter
|
142
|
-
requirement: !ruby/object:Gem::Requirement
|
143
|
-
requirements:
|
144
|
-
- - ">="
|
145
|
-
- !ruby/object:Gem::Version
|
146
|
-
version: '0'
|
147
|
-
type: :development
|
148
|
-
prerelease: false
|
149
|
-
version_requirements: !ruby/object:Gem::Requirement
|
150
|
-
requirements:
|
151
|
-
- - ">="
|
152
|
-
- !ruby/object:Gem::Version
|
153
|
-
version: '0'
|
154
140
|
- !ruby/object:Gem::Dependency
|
155
141
|
name: with_model
|
156
142
|
requirement: !ruby/object:Gem::Requirement
|
@@ -238,7 +224,7 @@ homepage: https://github.com/appbot/kms_rails
|
|
238
224
|
licenses:
|
239
225
|
- GPLv3
|
240
226
|
metadata: {}
|
241
|
-
post_install_message:
|
227
|
+
post_install_message:
|
242
228
|
rdoc_options: []
|
243
229
|
require_paths:
|
244
230
|
- lib
|
@@ -246,16 +232,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
246
232
|
requirements:
|
247
233
|
- - ">="
|
248
234
|
- !ruby/object:Gem::Version
|
249
|
-
version: '2.
|
235
|
+
version: '2.5'
|
250
236
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
251
237
|
requirements:
|
252
238
|
- - ">="
|
253
239
|
- !ruby/object:Gem::Version
|
254
240
|
version: '0'
|
255
241
|
requirements: []
|
256
|
-
|
257
|
-
|
258
|
-
signing_key:
|
242
|
+
rubygems_version: 3.0.3
|
243
|
+
signing_key:
|
259
244
|
specification_version: 4
|
260
245
|
summary: AWS KMS encryption for ActiveRecord & ActiveJob.
|
261
246
|
test_files: []
|