kms_encrypted 0.3.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/guides/Google.md DELETED
@@ -1,131 +0,0 @@
1
- # Google KMS
2
-
3
- Add this line to your application’s Gemfile:
4
-
5
- ```ruby
6
- gem 'google-api-client'
7
- gem 'kms_encrypted'
8
- ```
9
-
10
- Add columns for the encrypted data and the encrypted KMS data keys
11
-
12
- ```ruby
13
- add_column :users, :encrypted_email, :text
14
- add_column :users, :encrypted_email_iv, :text
15
- add_column :users, :encrypted_kms_key, :text
16
- ```
17
-
18
- Create a [Google Cloud Platform](https://cloud.google.com/) account if you don’t have one. KMS works great whether or not you run your infrastructure on GCP.
19
-
20
- Create a [KMS key ring and key](https://console.cloud.google.com/iam-admin/kms) and set it in your environment along with your GCP credentials ([dotenv](https://github.com/bkeepers/dotenv) is great for this)
21
-
22
- ```sh
23
- KMS_KEY_ID=projects/.../locations/.../keyRings/.../cryptoKeys/...
24
- ```
25
-
26
- And update your model
27
-
28
- ```ruby
29
- class User < ApplicationRecord
30
- has_kms_key
31
-
32
- attr_encrypted :email, key: :kms_key
33
- end
34
- ```
35
-
36
- For each encrypted attribute, use the `kms_key` method for its key.
37
-
38
- ## Auditing
39
-
40
- Follow the [instructions here](https://cloud.google.com/kms/docs/logging) to set up data access logging. To know what data is being decrypted, you’ll need to add context.
41
-
42
- Add a `kms_encryption_context` method to your model.
43
-
44
- ```ruby
45
- class User < ApplicationRecord
46
- def kms_encryption_context
47
- # some hash
48
- end
49
- end
50
- ```
51
-
52
- The context is used as part of the encryption and decryption process, so it must be a value that doesn’t change. Otherwise, you won’t be able to decrypt.
53
-
54
- The primary key is a good choice, but auto-generated ids aren’t available until a record is created, and we need to encrypt before this. One solution is to preload the primary key. Here’s what it looks like with Postgres:
55
-
56
- ```ruby
57
- class User < ApplicationRecord
58
- def kms_encryption_context
59
- self.id ||= self.class.connection.execute("select nextval('#{self.class.sequence_name}')").first["nextval"]
60
- {"Record" => "#{model_name}/#{id}"}
61
- end
62
- end
63
- ```
64
-
65
- ## Alerting
66
-
67
- We recommend setting up alerts on suspicious behavior.
68
-
69
- ## Key Rotation
70
-
71
- To manually rotate keys, replace the old key id with the new key id in your model. Your app does not need the old key id to perform rotation (however, the key must still be enabled in your GCP account).
72
-
73
- ```sh
74
- KMS_KEY_ID=...
75
- ```
76
-
77
- and run
78
-
79
- ```ruby
80
- User.find_each do |user|
81
- user.rotate_kms_key!
82
- end
83
- ```
84
-
85
- ## Testing
86
-
87
- For testing, you can prevent network calls to KMS by setting:
88
-
89
- ```sh
90
- KMS_KEY_ID=insecure-test-key
91
- ```
92
-
93
- ## Multiple Keys Per Record
94
-
95
- You may want to protect different columns with different data keys (or even master keys).
96
-
97
- To do this, add more columns
98
-
99
- ```ruby
100
- add_column :users, :encrypted_phone, :text
101
- add_column :users, :encrypted_phone_iv, :text
102
- add_column :users, :encrypted_kms_key_phone, :text
103
- ```
104
-
105
- And update your model
106
-
107
- ```ruby
108
- class User < ApplicationRecord
109
- has_kms_key
110
- has_kms_key name: :phone, key_id: "..."
111
-
112
- attr_encrypted :email, key: :kms_key
113
- attr_encrypted :phone, key: :kms_key_phone
114
- end
115
- ```
116
-
117
- For context, use:
118
-
119
- ```ruby
120
- class User < ApplicationRecord
121
- def kms_encryption_context_phone
122
- # some hash
123
- end
124
- end
125
- ```
126
-
127
- To rotate keys, use:
128
-
129
- ```ruby
130
- user.rotate_kms_key_phone!
131
- ```
data/guides/Vault.md DELETED
@@ -1,143 +0,0 @@
1
- # Vault
2
-
3
- Add this line to your application’s Gemfile:
4
-
5
- ```ruby
6
- gem 'vault'
7
- gem 'kms_encrypted'
8
- ```
9
-
10
- Add columns for the encrypted data and the encrypted KMS data keys
11
-
12
- ```ruby
13
- add_column :users, :encrypted_email, :text
14
- add_column :users, :encrypted_email_iv, :text
15
- add_column :users, :encrypted_kms_key, :text
16
- ```
17
-
18
- Enable the [transit](https://www.vaultproject.io/docs/secrets/transit/index.html) backend
19
-
20
- ```sh
21
- vault secrets enable transit
22
- ```
23
-
24
- And create a key
25
-
26
- ```sh
27
- vault write -f transit/keys/my-key
28
- ```
29
-
30
- Set it in your environment along with your Vault credentials ([dotenv](https://github.com/bkeepers/dotenv) is great for this)
31
-
32
- ```sh
33
- KMS_KEY_ID=vault/my-key
34
- VAULT_ADDR=http://127.0.0.1:8200
35
- VAULT_TOKEN=secret
36
- ```
37
-
38
- And update your model
39
-
40
- ```ruby
41
- class User < ApplicationRecord
42
- has_kms_key
43
-
44
- attr_encrypted :email, key: :kms_key
45
- end
46
- ```
47
-
48
- For each encrypted attribute, use the `kms_key` method for its key.
49
-
50
- ## Auditing
51
-
52
- Follow the [instructions here](https://www.vaultproject.io/docs/audit/) to set up data access logging. To know what data is being decrypted, you’ll need to add context.
53
-
54
- Add a `kms_encryption_context` method to your model.
55
-
56
- ```ruby
57
- class User < ApplicationRecord
58
- def kms_encryption_context
59
- # some hash
60
- end
61
- end
62
- ```
63
-
64
- The context is used as part of the encryption and decryption process, so it must be a value that doesn’t change. Otherwise, you won’t be able to decrypt. Read more about [encryption context here](https://docs.aws.amazon.com/kms/latest/developerguide/encryption-context.html).
65
-
66
- The primary key is a good choice, but auto-generated ids aren’t available until a record is created, and we need to encrypt before this. One solution is to preload the primary key. Here’s what it looks like with Postgres:
67
-
68
- ```ruby
69
- class User < ApplicationRecord
70
- def kms_encryption_context
71
- self.id ||= self.class.connection.execute("select nextval('#{self.class.sequence_name}')").first["nextval"]
72
- {"Record" => "#{model_name}/#{id}"}
73
- end
74
- end
75
- ```
76
-
77
- ## Alerting
78
-
79
- We recommend setting up alerts on suspicious behavior.
80
-
81
- ## Key Rotation
82
-
83
- To manually rotate keys, replace the old key id with the new key id in your model.
84
-
85
- ```sh
86
- KMS_KEY_ID=...
87
- ```
88
-
89
- and run
90
-
91
- ```ruby
92
- User.find_each do |user|
93
- user.rotate_kms_key!
94
- end
95
- ```
96
-
97
- ## Testing
98
-
99
- For testing, you can prevent network calls to KMS by setting:
100
-
101
- ```sh
102
- KMS_KEY_ID=insecure-test-key
103
- ```
104
-
105
- ## Multiple Keys Per Record
106
-
107
- You may want to protect different columns with different data keys (or even master keys).
108
-
109
- To do this, add more columns
110
-
111
- ```ruby
112
- add_column :users, :encrypted_phone, :text
113
- add_column :users, :encrypted_phone_iv, :text
114
- add_column :users, :encrypted_kms_key_phone, :text
115
- ```
116
-
117
- And update your model
118
-
119
- ```ruby
120
- class User < ApplicationRecord
121
- has_kms_key
122
- has_kms_key name: :phone, key_id: "..."
123
-
124
- attr_encrypted :email, key: :kms_key
125
- attr_encrypted :phone, key: :kms_key_phone
126
- end
127
- ```
128
-
129
- For context, use:
130
-
131
- ```ruby
132
- class User < ApplicationRecord
133
- def kms_encryption_context_phone
134
- # some hash
135
- end
136
- end
137
- ```
138
-
139
- To rotate keys, use:
140
-
141
- ```ruby
142
- user.rotate_kms_key_phone!
143
- ```
@@ -1,34 +0,0 @@
1
- # coding: utf-8
2
- lib = File.expand_path("../lib", __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "kms_encrypted/version"
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "kms_encrypted"
8
- spec.version = KmsEncrypted::VERSION
9
- spec.authors = ["Andrew Kane"]
10
- spec.email = ["andrew@chartkick.com"]
11
-
12
- spec.summary = "Simple, secure key management for attr_encrypted"
13
- spec.homepage = "https://github.com/ankane/kms_encrypted"
14
- spec.license = "MIT"
15
-
16
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
- f.match(%r{^(test|spec|features)/})
18
- end
19
- spec.bindir = "exe"
20
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
- spec.require_paths = ["lib"]
22
-
23
- spec.add_dependency "activesupport"
24
-
25
- spec.add_development_dependency "bundler"
26
- spec.add_development_dependency "rake"
27
- spec.add_development_dependency "minitest"
28
- spec.add_development_dependency "sqlite3"
29
- spec.add_development_dependency "activerecord"
30
- spec.add_development_dependency "attr_encrypted"
31
- spec.add_development_dependency "aws-sdk-kms"
32
- spec.add_development_dependency "google-api-client"
33
- spec.add_development_dependency "vault"
34
- end