Skip to main content
In this guide, you’ll learn how to secure secret data at rest in Kubernetes by encrypting it inside the etcd datastore. We cover creating secret objects, inspecting their base64-encoded storage, and finally enabling encryption at rest through an encryption configuration. This step-by-step process helps ensure that confidential information remains protected even if someone gains access to your etcd datastore.

1. Creating a Secret in Kubernetes

Begin by launching your single-node Kubernetes playground built with Kubernetes and ContainerD. Open your terminal to create a secret object using various methods. Here are several examples:
Additional customization options include:
  • --allow-missing-template-keys=true
  • --append-hash=false
  • --dry-run='none'
After creating the secret, verify its existence with:
To inspect the secret details:
And view its YAML representation:
Notice that the secret data is stored using Base64 encoding. For example:
This demonstrates that anyone with access to the secret manifest can decode the data.
Storing secrets in base64 does not provide true security. Without encryption at rest, confidential data can be exposed by anyone with direct access to the etcd datastore.

2. Inspecting Secrets in etcd

Now, explore how Kubernetes stores secret data in etcd. The secret data is persisted under paths such as /registry/secrets/default/secret1.

Viewing Unencrypted Data via etcdctl

You can use the etcdctl client (with API version 3) to view raw data stored in etcd. For example, run the following command:
A sample output might be:
Running the command with the secret key from our object yields similar unencrypted output, which clearly demonstrates that secret data (i.e., the password “supersecret”) is stored without encryption. Anybody with etcd access and the appropriate certificates can retrieve and decode this information.

3. Installing and Running etcdctl

If you encounter a missing etcdctl command, install it using your package manager. For Ubuntu users:
After installation, running etcdctl displays usage information along with a relevant warning regarding the API version:

4. Verifying etcd Data for Your Secrets

Ensure your Kubernetes cluster contains the necessary certificate files, such as /etc/kubernetes/pki/etcd/ca.crt. Then inspect the raw secrets stored in etcd using:
This unencrypted output verifies the vulnerability—anyone with etcd access can read the confidential data.

5. Determining if Encryption at Rest Is Enabled

Before proceeding further, confirm that the Kube API server is configured with an encryption provider. Check for the --encryption-provider-config flag in the process arguments or in the API server manifest file. If the flag is absent, you must enable encryption at rest for your secrets.
The image shows a Kubernetes documentation page about configuring and determining encryption at rest, including a caution for high-availability configurations.

6. Configuring Encryption at Rest

To secure your secret data at rest, create an encryption configuration file that specifies which resources to encrypt and which encryption providers to use. Create a file named “enc.yaml” with the following content:
Key points in this configuration:
  • The resource targeted for encryption is secrets.
  • The first provider uses the AES-CBC algorithm. Its key must be a base64-encoded 32-byte value (generate one with the command below if needed).
  • The identity provider acts as a fallback and will not encrypt data. Its placement after the AES-CBC provider ensures new secrets are encrypted.
Generate a key if needed:
Save the generated content into the file enc.yaml.

7. Updating the Kube API Server Manifest

To apply the encryption configuration, update the Kube API server manifest with the new encryption file reference. Follow these steps:
  1. Create a local directory to store the encryption file (e.g., /etc/kubernetes/enc).
  2. Move enc.yaml into this directory:
  3. Modify the Kube API server manifest (typically found at /etc/kubernetes/manifests/kube-apiserver.yaml) to include a new volume mount and add the --encryption-provider-config flag. An example snippet is as follows:
  4. Save your changes. The API server will restart and load the new configuration. Verify the running process with:
Ensure that the --encryption-provider-config flag is present and references the correct path.

8. Verifying Encryption of New Secrets

Once encryption is enabled, Kubernetes will encrypt all new secret objects in etcd. To test this, create a new secret:
Verify its creation:
Then inspect the secret data in etcd:
You should no longer see the plain text value “topsecret” in the output, confirming that the data is now encrypted. To update and re-encrypt pre-existing secrets, run:
This command re-writes each secret so that they are encrypted using the new configuration.

9. Conclusion

In this guide, we demonstrated how Kubernetes stores secret data as base64‑encoded strings in etcd, highlighting the vulnerabilities of unencrypted data. We then enabled encryption at rest by creating an encryption configuration file, updating the Kube API server manifest, and subsequently verifying that both new and updated secrets are securely encrypted. Following these steps is essential to protect critical data from unauthorized access. Thank you for reading this guide on encrypting secret data at rest in Kubernetes. For further details, refer to the Kubernetes Documentation.

Watch Video