Skip to content

Commit ec8a3cb

Browse files
authored
Merge pull request #44532 from sftim/20231226_encryption_at_rest
Improve docs around API data encryption at rest
2 parents b87d6e1 + e17cd06 commit ec8a3cb

File tree

1 file changed

+90
-12
lines changed

1 file changed

+90
-12
lines changed

content/en/docs/tasks/administer-cluster/encrypt-data.md

Lines changed: 90 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -562,21 +562,99 @@ For larger clusters, you may wish to subdivide the Secrets by namespace,
562562
or script an update.
563563
{{< /note >}}
564564

565-
## Rotating a decryption key
565+
## Prevent plain text retrieval {#cleanup-all-secrets-encrypted}
566566

567-
Changing a Secret without incurring downtime requires a multi-step operation, especially in
568-
the presence of a highly-available deployment where multiple `kube-apiserver` processes are running.
567+
If you want to make sure that the only access to a particular API kind is done using
568+
encryption, you can remove the API server's ability to read that API's backing data
569+
as plaintext.
569570

570-
1. Generate a new key and add it as the second key entry for the current provider on all servers
571-
1. Restart all `kube-apiserver` processes to ensure each server can decrypt using the new key
572-
1. Make the new key the first entry in the `keys` array so that it is used for encryption in the config
573-
1. Restart all `kube-apiserver` processes to ensure each server now encrypts using the new key
574-
1. Run `kubectl get secrets --all-namespaces -o json | kubectl replace -f -` to encrypt all
575-
existing Secrets with the new key
576-
1. Remove the old decryption key from the config after you have backed up etcd with the new key in use
577-
and updated all Secrets
571+
{{< warning >}}
572+
Making this change prevents the API server from retrieving resources that are marked
573+
as encrypted as rest, but are actually stored in the clear.
578574

579-
When running a single `kube-apiserver` instance, step 2 may be skipped.
575+
When you have configured encryption at rest for an API (for example: the API kind
576+
`Secret`, representing `secrets` resources in the core API group), you **must** ensure
577+
that all those resources in this cluster really are encrypted at rest. Check this before
578+
you carry on with the next steps.
579+
{{< /warning >}}
580+
581+
Once all Secrets in your cluster are encrypted, you can remove the `identity`
582+
part of the encryption configuration. For example:
583+
584+
{{< highlight yaml "linenos=false,hl_lines=12" >}}
585+
---
586+
apiVersion: apiserver.config.k8s.io/v1
587+
kind: EncryptionConfiguration
588+
resources:
589+
- resources:
590+
- secrets
591+
providers:
592+
- aescbc:
593+
keys:
594+
- name: key1
595+
secret: <BASE 64 ENCODED SECRET>
596+
- identity: {} # REMOVE THIS LINE
597+
{{< /highlight >}}
598+
599+
…and then restart each API server in turn. This change prevents the API server
600+
from accessing a plain-text Secret, even by accident.
601+
602+
## Rotate a decryption key {#rotating-a-decryption-key}
603+
604+
Changing an encryption key for Kubernetes without incurring downtime requires a multi-step operation,
605+
especially in the presence of a highly-available deployment where multiple `kube-apiserver` processes
606+
are running.
607+
608+
1. Generate a new key and add it as the second key entry for the current provider on all
609+
control plane nodes.
610+
1. Restart **all** `kube-apiserver` processes, to ensure each server can decrypt
611+
any data that are encrypted with the new key.
612+
1. Make a secure backup of the new encryption key. If you lose all copies of this key you would
613+
need to delete all the resources were encrypted under the lost key, and workloads may not
614+
operate as expected during the time that at-rest encryption is broken.
615+
1. Make the new key the first entry in the `keys` array so that it is used for encryption-at-rest
616+
for new writes
617+
1. Restart all `kube-apiserver` processes to ensure each control plane host now encrypts using the new key
618+
1. As a privileged user, run `kubectl get secrets --all-namespaces -o json | kubectl replace -f -`
619+
to encrypt all existing Secrets with the new key
620+
1. After you have updated all existing Secrets to use the new key and have made a secure backup of the
621+
new key, remove the old decryption key from the configuration.
622+
623+
## Decrypt all data {#decrypting-all-data}
624+
625+
This example shows how to stop encrypting the Secret API at rest. If you are encrypting
626+
other API kinds, adjust the steps to match.
627+
628+
To disable encryption at rest, place the `identity` provider as the first
629+
entry in your encryption configuration file:
630+
631+
```yaml
632+
---
633+
apiVersion: apiserver.config.k8s.io/v1
634+
kind: EncryptionConfiguration
635+
resources:
636+
- resources:
637+
- secrets
638+
# list any other resources here that you previously were
639+
# encrypting at rest
640+
providers:
641+
- identity: {} # add this line
642+
- aescbc:
643+
keys:
644+
- name: key1
645+
secret: <BASE 64 ENCODED SECRET> # keep this in place
646+
# make sure it comes after "identity"
647+
```
648+
649+
Then run the following command to force decryption of all Secrets:
650+
651+
```shell
652+
kubectl get secrets --all-namespaces -o json | kubectl replace -f -
653+
```
654+
655+
Once you have replaced all existing encrypted resources with backing data that
656+
don't use encryption, you can remove the encryption settings from the
657+
`kube-apiserver`.
580658

581659
## Configure automatic reloading
582660

0 commit comments

Comments
 (0)