It is possible for a KMSv2 plugin to return a static value as Ciphertext
and store the actual encrypted DEK in the annotations. In this case,
using the encDEK will not work. Instead, we are now using a combination
of the encDEK, keyID and annotations to generate the cache key.
Signed-off-by: Anish Ramasekar <anish.ramasekar@gmail.com>
Kubernetes-commit: 8eacf09649ac9042c7e998b5c24ac59d68ae7e6c
This change updates KMS v2 to not create a new DEK for every
encryption. Instead, we re-use the DEK while the key ID is stable.
Specifically:
We no longer use a random 12 byte nonce per encryption. Instead, we
use both a random 4 byte nonce and an 8 byte nonce set via an atomic
counter. Since each DEK is randomly generated and never re-used,
the combination of DEK and counter are always unique. Thus there
can never be a nonce collision. AES GCM strongly encourages the use
of a 12 byte nonce, hence the additional 4 byte random nonce. We
could leave those 4 bytes set to all zeros, but there is no harm in
setting them to random data (it may help in some edge cases such as
live VM migration).
If the plugin is not healthy, the last DEK will be used for
encryption for up to three minutes (there is no difference on the
behavior of reads which have always used the DEK cache). This will
reduce the impact of a short plugin outage while making it easy to
perform storage migration after a key ID change (i.e. simply wait
ten minutes after the key ID change before starting the migration).
The DEK rotation cycle is performed in sync with the KMS v2 status
poll thus we always have the correct information to determine if a
read is stale in regards to storage migration.
Signed-off-by: Monis Khan <mok@microsoft.com>
Kubernetes-commit: 832d6f0e19f13b9dd22b1fe9d705817e9e64f4f1
This change in a no-op refactor of the encryption at rest code that
primarily changes the wiring to consistently use context for
lifecycle management (instead of a mixture of context and stop
channels).
Signed-off-by: Monis Khan <mok@microsoft.com>
Kubernetes-commit: 70b414b0e5cbe9706e5a4fc0d7299ec6b169d642
This change enables hot reload of encryption config file when api server
flag --encryption-provider-config-automatic-reload is set to true. This
allows the user to change the encryption config file without restarting
kube-apiserver. The change is detected by polling the file and is done
by using fsnotify watcher. When file is updated it's process to generate
new set of transformers and close the old ones.
Signed-off-by: Nilekh Chaudhari <1626598+nilekhc@users.noreply.github.com>
Kubernetes-commit: 761b7822fca569d475f782b135ef433e5b014147
This change adds a flag --encryption-provider-config-automatic-reload
which will be used to drive automatic reloading of the encryption
config at runtime. While this flag is set to true, or when KMS v2
plugins are used without KMS v1 plugins, the /healthz endpoints
associated with said plugins are collapsed into a single endpoint at
/healthz/kms-providers - in this state, it is not possible to
configure exclusions for specific KMS providers while including the
remaining ones - ex: using /readyz?exclude=kms-provider-1 to exclude
a particular KMS is not possible. This single healthz check handles
checking all configured KMS providers. When reloading is enabled
but no KMS providers are configured, it is a no-op.
k8s.io/apiserver does not support dynamic addition and removal of
healthz checks at runtime. Reloading will instead have a single
static healthz check and swap the underlying implementation at
runtime when a config change occurs.
Signed-off-by: Monis Khan <mok@microsoft.com>
Kubernetes-commit: 22e540bc48d9bf698c4f381ccb56ed57dea0dae2
This change updates the API server code to load the encryption
config once at start up instead of multiple times. Previously the
code would set up the storage transformers and the etcd healthz
checks in separate parse steps. This is problematic for KMS v2 key
ID based staleness checks which need to be able to assert that the
API server has a single view into the KMS plugin's current key ID.
Signed-off-by: Monis Khan <mok@microsoft.com>
Kubernetes-commit: f507bc255382b2e2095351053bc17e74f7100d35
- add feature gate
- add encrypted object and run generated_files
- generate protobuf for encrypted object and add unit tests
- move parse endpoint to util and refactor
- refactor interface and remove unused interceptor
- add protobuf generate to update-generated-kms.sh
- add integration tests
- add defaulting for apiVersion in kmsConfiguration
- handle v1/v2 and default in encryption config parsing
- move metrics to own pkg and reuse for v2
- use Marshal and Unmarshal instead of serializer
- add context for all service methods
- check version and keyid for healthz
Signed-off-by: Anish Ramasekar <anish.ramasekar@gmail.com>
Kubernetes-commit: f19f3f409938ff9ac8a61966e47fbe9c6075ec90
Add location transformer, config for transformers
Location transformer helps choose the most specific transformer for
read/write operations depending on the path of resource being accessed.
Configuration allows use of --experimental-encryption-provider-config
to set up encryption providers. Only AEAD is supported at the moment.
Add new files to BUILD, AEAD => k8s-aes-gcm
Use group resources to select encryption provider
Update tests for configuration parsing
Remove location transformer
Allow specifying providers per resource group in configuration
Add IdentityTransformer configuration option
Fix minor issues with initial AEAD implementation
Unified parsing of all configurations
Parse configuration using a union struct
Run configuration parsing in APIserver, refactor parsing
More gdoc, fix minor bugs
Add test coverage for combined transformers
Use table driven tests for encryptionconfig
Kubernetes-commit: 9760d00d08ef0619e30a7b1b90fd290cab960069