forked from cloudfoundry/docs-cf-admin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
encrypting-cc-db.html.md.erb
187 lines (142 loc) · 7.27 KB
/
encrypting-cc-db.html.md.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
---
title: Encrypting Cloud Controller database and rotating keys
owner: CAPI
---
You can encrypt sensitive data in the Cloud Controller (CC) database with <%= vars.app_runtime_abbr %> by
using operator provided keys.
## <a id="encryption"></a>Enabling encryption
In the following steps, the examples show a single encryption key being configured and set as the current key, but multiple keys can be
stored under `keys`.
Multiple keys are allowed so that CC can decrypt your previously encrypted sensitive data before rotating to a new key.
Only the key with its label set as the `current_key_label` is used for encryption.
1. Choose a value for the encryption key (e.g. `"example-random-key-string"`).
1. Choose a label for the encryption key (e.g. `<%= vars.encryption_key %>`). The label must abide by the following restrictions:
* 127 character limit
* Cannot contain a `:` (colon)
1. Format the encryption key values into YAML as follows:
```
database_encryption:
current_key_label: "<%= vars.encryption_key %>"
keys:
<%= vars.encryption_key %>: "example-random-key-string"
```
<p> If your CC instance groups have the <code>db_encryption_key</code> key, ensure that you add
<code>db_encryption_key</code> to the <code>keys</code> block, and that you set its corresponding key label to value of <code>current_key_label</code>.
For example:</p>
```
db_encryption_key: "example-random-key-string"
database_encryption:
current_key_label: "<%= vars.encryption_key %>"
keys:
<%= vars.encryption_key %>: "example-random-key-string"
```
1. Make your changes by either creating and applying an [ops file](#configuring-via-ops-file) or directly modifying the [manifest](#configuring-via-manifest).
1. Deploy the changes with the command that corresponds to your use case:
* **With an ops file**
<pre class="terminal">
$ bosh deploy -o YOUR_OPS_FILE_NAME PATH_TO_YOUR_MANIFEST
</pre>
* **Direct modification of the manifest**
<pre class="terminal">
$ bosh deploy PATH_TO_YOUR_MANIFEST
</pre>
1. Run the bosh errand to encrypt the fields:
<pre class="terminal">$ bosh run-errand rotate-cc-database-key</pre>
1. Once the errand has run successfully, you can safely remove the `db_encryption_key` from the manifest.
<p> If you remove <code>db_encryption_key</code> from the manifest before you run the errand,
CC no longer is able to decrypt your previously encrypted sensitive data.</p>
### <a id="configuring-via-ops-file"></a>Configuring through an ops file
The recommended way of enabling encryption is to use an [ops file](https://bosh.io/docs/cli-ops-files/).
YAML anchors
(for example, `encryption_info` in the following example) can also be used to reduce repetition and ensure
consistency of encryption key properties across the instance groups.
For example, the following can be used as an ops file:
```
- type: replace
path: /instance_groups/name=api/jobs/name=cloud_controller_ng/properties/cc/database_encryption?
value: &encryption_info
keys:
<%= vars.encryption_key %>: "example-random-key-string"
current_key_label: "<%= vars.encryption_key %>"
- type: replace
path: /instance_groups/name=cc-worker/jobs/name=cloud_controller_worker/properties/cc/database_encryption?
value: *encryption_info
- type: replace
path: /instance_groups/name=scheduler/jobs/name=cloud_controller_clock/properties/cc/database_encryption?
value: *encryption_info
```
### <a id="configuring-via-manifest"></a>Configuring through the manifest
For each CC instance group (`api`, `cc-worker`, `scheduler`) in the manifest,
insert the `database_encryption` YAML block so that the final YAML looks like the following:
```
instance_groups:
api:
jobs:
cloud_controller_ng:
properties:
database_encryption: &encryption_info
keys:
<%= vars.encryption_key %>: "example-random-key-string"
current_key_label: "<%= vars.encryption_key %>"
...
cc-worker:
jobs:
cloud_controller_ng:
properties:
database_encryption: *encryption_info
...
scheduler:
jobs:
cloud_controller_ng:
properties:
database_encryption: *encryption_info
```
<p class="note">
<span class="note__title"><strong>Note</strong></span>
The <code>keys</code> and <code>current_key_label</code> field must match across all
instance groups - our example uses YAML anchors to achieve this.</p>
## <a id="validation"></a>Validating encryption properties
The CC runs validations before and during deployment to ensure that it can decrypt all previously encrypted sensitive data.
The following are validated:
* The `db_encryption_key` is present if used in the database.
* The `current_key_label` exists in the `keys` hash.
* The key associated with an encryption key label in the `keys` hash does not change.
* All in-use encryption key label/value pairs exist in the `keys` hash.
In certain situations, you can decide to skip these validations for a deploy to complete successfully.
They can do so by setting the `database_encryption.skip_validation` property to `true` temporarily.
<p class="note">
<span class="note__title"><strong>Note</strong></span>
Skipping database encryption validation is <strong>not</strong> recommended.</p>
## <a id="rotation"></a>Rotating encryption keys
<p> It is important that the mapping between the encryption key labels and key values in the <code>database_encryption.keys</code>
property be maintained.
If this mapping is not maintained, it leads to loss of access to encrypted values in the database.
The correct way to add a new key is described in the following steps.</p>
In order to rotate an encryption key:
1. Add a new encryption key to the list of `keys` (e.g. `<%= vars.rotated_key %>`.
1. Update the `current_key_label` to be the label of the new encryption key (for example, updating the `current_key_label` to be `"<%= vars.rotated_key %>").
The following is an example of an ops file used for rotation:
```
- type: replace
path: /instance_groups/name=api/jobs/name=cloud_controller_ng/properties/cc/database_encryption?
value: &encryption_info
keys:
<%= vars.encryption_key %>: "example-random-key-string"
<%= vars.rotated_key %>: "other-random-key-string"
current_key_label: "<%= vars.rotated_key %>"
- type: replace
path: /instance_groups/name=cc-worker/jobs/name=cloud_controller_worker/properties/cc/database_encryption?
value: *encryption_info
- type: replace
path: /instance_groups/name=scheduler/jobs/name=cloud_controller_clock/properties/cc/database_encryption?
value: *encryption_info
```
1. Deploy the changes by running the following command.
<pre class="terminal">$ bosh deploy -o YOUR_OPS_FILE_NAME PATH_TO_YOUR_MANIFEST</pre>
<p> Whether the errand is run or not, any updates to sensitive data is encrypted with
the new key.</p>
1. Run the bosh errand command to rotate the encryption key.
<pre class="terminal">$ bosh run-errand rotate-cc-database-key</pre>
1. Once the errand has run successfully, you can safely remove the old key from the manifest.
<p> If you remove the old key from the manifest before running the errand,
CC is no longer able to decrypt your previously encrypted sensitive data.</p>