Skip to content

Commit 6d3d847

Browse files
authored
Merge pull request #2 from aramase/3299-kms-v2
chore: use snake case for non-generated proto API
2 parents 2ea5c24 + b4a4b95 commit 6d3d847

File tree

1 file changed

+20
-20
lines changed
  • keps/sig-auth/3299-kms-v2-improvements

1 file changed

+20
-20
lines changed

keps/sig-auth/3299-kms-v2-improvements/README.md

+20-20
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,11 @@ Performance, Health Check, Observability and Rotation:
9292
- Support key hierarchy in KMS plugin that generates local KEK
9393
- Expand `EncryptionConfiguration` to support a new KMSv2 configuration
9494
- Add v2alpha1 `KeyManagementService` proto service contract in Kubernetes to include
95-
- `currentKeyID` and metadata to support key rotation
96-
- `currentKeyID`: the KMS Key ID, stable identifier, changed to trigger key rotation and storage migration
95+
- `current_key_id` and metadata to support key rotation
96+
- `current_key_id`: the KMS Key ID, stable identifier, changed to trigger key rotation and storage migration
9797
- metadata: structured data, can contain the encrypted local KEK, can be used for debugging, recovery, opaque to API server, stored unencrypted, etc. Validation similar to how K8s labels are validated today. Labels have good size limits and restrictions today.
98-
- A status request and response periodically (order of minutes) returns `version`, `healthz`, and `currentKeyID`
99-
- The `currentKeyID` in status can be used on decrypt operations to compare and validate the key ID stored in the DEK cache and the latest `EncryptResponse` `currentKeyID` to detect if an object is stale in terms of storage migration
98+
- A status request and response periodically (order of minutes) returns `version`, `healthz`, and `current_key_id`
99+
- The `current_key_id` in status can be used on decrypt operations to compare and validate the key ID stored in the DEK cache and the latest `EncryptResponse` `current_key_id` to detect if an object is stale in terms of storage migration
100100
- Generate a new UID for each envelope operation in kube-apiserver
101101
- Add a new UID field to `EncryptRequest` and `DecryptRequest`
102102
- Add support for hot reload of the `EncryptionConfiguration`:
@@ -149,7 +149,7 @@ index d7d68d2584d..84c1fa6546f 100644
149149
+}
150150
```
151151

152-
Support key hierarchy in KMS plugin that generates local KEK and add v2alpha1 `KeyManagementService` proto service contract in Kubernetes to include `currentKeyID`, `metadata`, and `status`.
152+
Support key hierarchy in KMS plugin that generates local KEK and add v2alpha1 `KeyManagementService` proto service contract in Kubernetes to include `current_key_id`, `metadata`, and `status`.
153153

154154
Key Hierarchy in KMS plugin (reference implementation):
155155

@@ -163,7 +163,7 @@ Key Hierarchy in KMS plugin (reference implementation):
163163

164164
Since key hierarchy is implemented at the KMS plugin level, it should be seamless for the kube-apiserver. So whether the plugin is using a key hierarchy or not, the kube-apiserver should behave the same.
165165

166-
What is required of the kube-apiserver is to be able to tell the KMS plugin which KEK (local KEK or KMS KEK) it should use to decrypt the incoming DEK. To do so, upon encryption, the KMS plugin could provide the encrypted local KEK as part of the `metadata` field in the `EncryptResponse`. The kube-apiserver would then store it in etcd next to the DEK. Upon decryption, the kube-apiserver provides the encrypted local KEK in `metadata` and `observedKeyID` from the last encryption when calling Decrypt. In case no encrypted local KEK is provided in the `metadata`, then we can assume key hierarchy is not used. The KMS plugin would query the external KMS to use the remote KEK to decrypt the DEK (same behavior as today). No state coordination is required between different instances of the KMS plugin.
166+
What is required of the kube-apiserver is to be able to tell the KMS plugin which KEK (local KEK or KMS KEK) it should use to decrypt the incoming DEK. To do so, upon encryption, the KMS plugin could provide the encrypted local KEK as part of the `metadata` field in the `EncryptResponse`. The kube-apiserver would then store it in etcd next to the DEK. Upon decryption, the kube-apiserver provides the encrypted local KEK in `metadata` and `observed_key_id` from the last encryption when calling Decrypt. In case no encrypted local KEK is provided in the `metadata`, then we can assume key hierarchy is not used. The KMS plugin would query the external KMS to use the remote KEK to decrypt the DEK (same behavior as today). No state coordination is required between different instances of the KMS plugin.
167167

168168
For the reference KMS plugin, the encrypted local KEK is stored in etcd via the `metadata` field, and once decrypted, it can be stored in memory as part of the KMS plugin cache to be used for encryption and decryption of DEKs. The encrypted local KEK is used as the key and the decrypted local KEK is stored as the value.
169169

@@ -173,15 +173,15 @@ message EncryptResponse {
173173
bytes ciphertext = 1;
174174
// The KMS key ID used for encryption operations.
175175
// This can be used to drive rotation.
176-
string currentKeyID = 2;
176+
string current_key_id = 2;
177177
// Additional metadata to be stored with the encrypted data.
178178
// This metadata can contain the encrypted local KEK that was used to encrypt the DEK.
179179
// Stored unencrypted in etcd.
180180
map<string, string> metadata = 3;
181181
}
182182
```
183183

184-
The `DecryptRequest` passes the same `currentKeyID` and `metadata` returned by the previous `EncryptResponse` of this data as its `observedKeyID` and `metadata` for the decryption request.
184+
The `DecryptRequest` passes the same `current_key_id` and `metadata` returned by the previous `EncryptResponse` of this data as its `observed_key_id` and `metadata` for the decryption request.
185185

186186
```proto
187187
message DecryptRequest {
@@ -191,7 +191,7 @@ message DecryptRequest {
191191
string uid = 3;
192192
// The keyID that was provided to the apiserver during encryption.
193193
// This represents the KMS KEK that was used to encrypt the data.
194-
string observedKeyID = 4;
194+
string observed_key_id = 4;
195195
// Additional metadata that was sent by the KMS plugin during encryption.
196196
map<string, string> metadata = 5;
197197
}
@@ -200,7 +200,7 @@ message DecryptResponse {
200200
// The decrypted data.
201201
bytes plaintext = 1;
202202
// The KMS key ID used to decrypt the data.
203-
string currentKeyID = 2;
203+
string current_key_id = 2;
204204
// Additional metadata that was sent by the KMS plugin.
205205
map<string, string> metadata = 3;
206206
}
@@ -248,11 +248,11 @@ message StatusResponse {
248248
string healthz = 2;
249249
250250
// the current write key, can be used to trigger rotation
251-
string currentKeyID = 3;
251+
string current_key_id = 3;
252252
}
253253
```
254254

255-
The `currentKeyID` may be funneled into the storage version status as another field that API servers can attempt to gain consensus on:
255+
The `current_key_id` may be funneled into the storage version status as another field that API servers can attempt to gain consensus on:
256256

257257
```diff
258258
diff --git a/staging/src/k8s.io/api/apiserverinternal/v1alpha1/types.go b/staging/src/k8s.io/api/apiserverinternal/v1alpha1/types.go
@@ -306,12 +306,12 @@ sequenceDiagram
306306
kmsplugin->>externalkms: encrypt local KEK with remote KEK
307307
externalkms->>kmsplugin: encrypted local KEK
308308
kmsplugin->>kmsplugin: cache encrypted local KEK
309-
kmsplugin->>kubeapiserver: return encrypt response <br/> {"ciphertext": "<encrypted DEK>", currentKeyID: "<remote KEK ID>", <br/> "metadata": {"kms.kubernetes.io/local-kek": "<encrypted local KEK>"}}
309+
kmsplugin->>kubeapiserver: return encrypt response <br/> {"ciphertext": "<encrypted DEK>", current_key_id: "<remote KEK ID>", <br/> "metadata": {"kms.kubernetes.io/local-kek": "<encrypted local KEK>"}}
310310
else not using key hierarchy
311311
%% current behavior
312312
kmsplugin->>externalkms: encrypt DEK with remote KEK
313313
externalkms->>kmsplugin: encrypted DEK
314-
kmsplugin->>kubeapiserver: return encrypt response <br/> {"ciphertext": "<encrypted DEK>", currentKeyID: "<remote KEK ID>", "metadata": {}}
314+
kmsplugin->>kubeapiserver: return encrypt response <br/> {"ciphertext": "<encrypted DEK>", current_key_id: "<remote KEK ID>", "metadata": {}}
315315
end
316316
kubeapiserver->>etcd: store encrypt response and encrypted DEK
317317
```
@@ -325,7 +325,7 @@ sequenceDiagram
325325
participant externalkms
326326
%% if local KEK in metadata, then using hierarchy
327327
alt encrypted local KEK is in metadata
328-
kubeapiserver->>kmsplugin: decrypt request <br/> {"ciphertext": "<encrypted DEK>", observedKeyID: "<currentKeyID gotten as part of EncryptResponse>", <br/> "metadata": {"kms.kubernetes.io/local-kek": "<encrypted local KEK>"}}
328+
kubeapiserver->>kmsplugin: decrypt request <br/> {"ciphertext": "<encrypted DEK>", observed_key_id: "<current_key_id gotten as part of EncryptResponse>", <br/> "metadata": {"kms.kubernetes.io/local-kek": "<encrypted local KEK>"}}
329329
alt encrypted local KEK in cache
330330
kmsplugin->>kmsplugin: decrypt DEK with local KEK
331331
else encrypted local KEK not in cache
@@ -334,12 +334,12 @@ sequenceDiagram
334334
kmsplugin->>kmsplugin: decrypt DEK with local KEK
335335
kmsplugin->>kmsplugin: cache decrypted local KEK
336336
end
337-
kmsplugin->>kubeapiserver: return decrypt response <br/> {"plaintext": "<decrypted DEK>", currentKeyID: "<remote KEK ID>", <br/> "metadata": {"kms.kubernetes.io/local-kek": "<encrypted local KEK>"}}
337+
kmsplugin->>kubeapiserver: return decrypt response <br/> {"plaintext": "<decrypted DEK>", current_key_id: "<remote KEK ID>", <br/> "metadata": {"kms.kubernetes.io/local-kek": "<encrypted local KEK>"}}
338338
else encrypted local KEK is not in metadata
339-
kubeapiserver->>kmsplugin: decrypt request <br/> {"ciphertext": "<encrypted DEK>", observedKeyID: "<currentKeyID gotten as part of EncryptResponse>", <br/> "metadata": {}}
339+
kubeapiserver->>kmsplugin: decrypt request <br/> {"ciphertext": "<encrypted DEK>", observed_key_id: "<current_key_id gotten as part of EncryptResponse>", <br/> "metadata": {}}
340340
kmsplugin->>externalkms: decrypt DEK with remote KEK (same behavior as today)
341341
externalkms->>kmsplugin: decrypted DEK
342-
kmsplugin->>kubeapiserver: return decrypt response <br/> {"plaintext": "<decrypted DEK>", currentKeyID: "<remote KEK ID>", <br/> "metadata": {}}
342+
kmsplugin->>kubeapiserver: return decrypt response <br/> {"plaintext": "<decrypted DEK>", current_key_id: "<remote KEK ID>", <br/> "metadata": {}}
343343
end
344344
```
345345

@@ -431,7 +431,7 @@ Yes, via the `KMSv2` feature gate. Disabling this gate without first doing a sto
431431
###### How can someone using this feature know that it is working for their instance?
432432

433433
- [x] Other (treat as last resort)
434-
- Details: Logs in kube-apiserver, kms-plugin and KMS will be logged with the corresponding `observedKeyID`, `metadata`, and `UID`.
434+
- Details: Logs in kube-apiserver, kms-plugin and KMS will be logged with the corresponding `observed_key_id`, `metadata`, and `UID`.
435435

436436
###### What are the reasonable SLOs (Service Level Objectives) for the enhancement?
437437

@@ -440,7 +440,7 @@ There should be no impact on the SLO with this change.
440440
###### What are the SLIs (Service Level Indicators) an operator can use to determine the health of the service?
441441

442442
- [x] Other (treat as last resort)
443-
- Details: Logs in kube-apiserver, kms-plugin and KMS will be logged with the corresponding `observedKeyID`, `metadata`, and `UID`.
443+
- Details: Logs in kube-apiserver, kms-plugin and KMS will be logged with the corresponding `observed_key_id`, `metadata`, and `UID`.
444444

445445
### Dependencies
446446

0 commit comments

Comments
 (0)