Types of Encryption for Kubernetes Secrets

Nidhi Ashtikar
8 min readJun 3, 2024

--

As requested by the readers, Let me explore more about “Types of Encryption for Kubernetes Secrets”

Check out the article below: How to Encrypt Kubernetes Secrets?

Kubernetes supports several methods to encrypt secrets, each providing different levels of security and control. Here are the main types of encryption for Kubernetes secrets:

  • Base64 Encoding: Default, minimal security.
  • KMS Provider: External key management, high security.
  • AESCBC Provider: Strong encryption, manual key management.
  • Secretbox Provider: Strong encryption, manual key management.
  • Identity Provider: No encryption, for testing only.
  • Configurable Encryption: Allows combining multiple encryption methods for flexible and layered security.

1. Base64 Encoding (Default):

  • Not true encryption but a means to obfuscate data.
  • Secrets in Kubernetes are base64-encoded by default.
  • Base64 encoding does not provide security; it only hides the plaintext data.

2. Encryption at Rest:

1. KMS Provider:

  • Integrates with external Key Management Services (KMS) like AWS KMS, Azure Key Vault, or Google Cloud KMS.
  • The KMS provider encrypts the secrets using keys managed outside the Kubernetes cluster.
  • Provides high security as it leverages the advanced features of cloud provider KMS solutions.

AWS KMS Encryption:

Key Requirements :

  • The KMS key must be symmetric.
  • It should be able to encrypt and decrypt data.
  • The KMS key must be created in the same AWS Region as the Kubernetes cluster.
  • If the KMS key was created in a different AWS account, the IAM principal (user or role) must have access to that KMS key.

Enabling Encryption:

  • You can enable encryption in two ways:
  • Using a single command:
eksctl utils enable-secrets-encryption \
--cluster my-cluster \
--key-arn arn:aws:kms:region-code:account:key/key
  • Using a kms-cluster.yaml file:
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: my-cluster
region: region-code
secretsEncryption:
keyARN: arn:aws:kms:region-code:account:key/key

Re-encrypting Existing Secrets:

  • After enabling encryption, you must re-encrypt all existing secrets with the new key.
  • Use the following command:
kubectl get secrets --all-namespaces -o json | kubectl annotate --overwrite -f - kms-encryption-timestamp="time value"

2. AESCBC Provider:

  • Uses AES-CBC (Cipher Block Chaining) mode encryption with a 256-bit key.
  • Keys must be managed manually and rotated within the Kubernetes configuration.

3. Secretbox Provider:

  • Uses NaCl (Networking and Cryptography library) Secretbox for secret encryption.
  • Utilizes XSalsa20 and Poly1305 for authenticated encryption.
  • Keys must be managed manually and rotated within the Kubernetes configuration.

4. Identity Provider:

  • Provides plaintext storage without any encryption.
  • Primarily used for testing and not recommended for production environments.

3. Encryption Configuration:

  • Kubernetes supports a configurable encryption mechanism where multiple encryption providers can be specified using a layered approach.
  • A configuration file specifies the order and type of encryption providers, allowing for flexible and secure storage of secrets.
  • This allows for strategies such as using the KMS provider first, followed by AESCBC, and so on.

Encryption Configuration Example:

apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- kms:
name: myKMSProvider
endpoint: unix:///var/run/kms-provider.sock
cachesize: 1000
timeout: 3s
- aescbc:
keys:
- name: key1
secret: <base64-encoded-256-bit-key>
- secretbox:
keys:
- name: key1
secret: <base64-encoded-32-byte-key>
- identity: {}

Steps to Implement Encryption at Rest:

  1. Create an Encryption Configuration File: Define the encryption providers and the order of their applications.
  2. Reference the Configuration in the API Server: Modify the API server manifest to include the --encryption-provider-config flag pointing to the encryption configuration file.
  3. Restart the API Server: Apply the new configuration by restarting the API server.

By utilizing these methods, Kubernetes ensures that sensitive data is secured, whether it is at rest or being managed by the cluster. Proper key management and encryption strategies are essential to maintaining the confidentiality and integrity of secrets within a Kubernetes environment.

In Kubernetes, Secrets are crucial in managing sensitive information such as passwords, OAuth tokens, and SSH keys.
We’ll explore the various types of encryption available for Kubernetes Secrets from the official Kubernetes documentation.

1. Opaque Secrets:

Opaque secrets are the default secret type in Kubernetes. When you create a Secret without specifying a type, it defaults to Opaque.

Functionality:

  • Stores arbitrary key-value pairs as base64-encoded strings.
  • Useful for generic secret data.

Example:

apiVersion: v1
kind: Secret
metadata:
name: my-secret
data:
username: YWRtaW4= # base64-encoded "admin"
password: cGFzc3dvcmQ= # base64-encoded "password"

2. ServiceAccount Token Secrets:

Automatically created by Kubernetes for each ServiceAccount.

Purpose:

  • Used for authenticating with the Kubernetes API server.
  • Contains a token and a CA certificate.

3. Docker Config Secrets:

Used for serializing Docker configuration files.

Use Case:

  • Includes authentication details for Docker registries.
apiVersion: v1
kind: Secret
metadata:
name: docker-config-secret
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: <base64-encoded Docker config.json>

4. Basic Authentication Secrets:

Stores username and password pairs.

Scenario:

  • Useful for authenticating with external services.
apiVersion: v1
kind: Secret
metadata:
name: basic-auth-secret
type: Opaque
data:
username: YWRtaW4= # base64-encoded "admin"
password: cGFzc3dvcmQ= # base64-encoded "password"

5. SSH Authentication Secrets:

Used for SSH key pairs.

Application:

  • Useful for Git repositories or other SSH-based services.
apiVersion: v1
kind: Secret
metadata:
name: ssh-key-secret
type: kubernetes.io/ssh-auth
data:
ssh-privatekey: <base64-encoded private key>

6. TLS Secrets:

Stores TLS certificates and private keys.

Usage:

  • Used for securing communication between services.
apiVersion: v1
kind: Secret
metadata:
name: tls-secret
type: kubernetes.io/tls
data:
tls.crt: <base64-encoded certificate>
tls.key: <base64-encoded private key>

7. BootStrap Token Secrets:

Used during cluster bootstrap.

Contains:

  • Tokens for initial authentication.

Best Practices for Cluster Administrators:

Configure Encryption at Rest:

  • By default, Secret objects are stored unencrypted in etcd. Configure encryption of your Secret data in etcd to enhance security.
  • Refer to the official documentation on Encrypting Secret Data at Rest for instructions.

Least-Privilege Access to Secrets:

  • Restrict access to Secrets based on roles and responsibilities.
  • Follow Kubernetes Role-based Access Control (RBAC) guidelines.
  • Limit access to Secrets to only the necessary components and users.

Additional ServiceAccount Annotations:

  • Use the kubernetes.io/enforce-mountable-secrets annotation on a ServiceAccount to enforce specific rules on how Secrets are used in Pods.

Remember that while Secrets are encoded as base64 strings, they are stored unencrypted by default.
To improve security, enable encryption at rest and ensure that secret data is encrypted before being written to etcd.
By following these practices, you can effectively manage your Secrets and enhance the security of your Kubernetes clusters.

These guidelines are intended for both cluster administrators and application developers. Implementing them will help you safeguard sensitive information and maintain a robust Secrets management system within your Kubernetes environment

How is this (Secrets)stored in k8s? Is it plain text in etcd? i.e. if etcd is compromised, are all secrets compromised?

Kubernetes Secrets are a critical component for managing sensitive information, but understanding how they are stored and secured is essential.

Storage in Kubernetes:

  • By default, Kubernetes Secrets are stored unencrypted in the API server’s underlying data store, which is typically etcd.
  • Anyone with API access can retrieve or modify a Secret, and so can anyone with access to etcd.

Base64 Encoding:

  • Secrets are encoded as base64 strings within Kubernetes.
  • However, base64 encoding is not encryption; it’s merely an encoding mechanism.
  • If etcd is compromised, an attacker can easily decode the base64-encoded secrets.

Risk of Compromise:

  • If etcd is compromised, all secrets stored in it are potentially exposed.
  • This includes not only the secret values but also metadata like names and labels.

To Enhance security:

  • Configure Encryption at Rest: Encrypt Secret data in etcd. Refer to the official documentation on Encrypting Secret Data at Rest.
  • Least-Privilege Access: Restrict access to Secrets based on roles and responsibilities using Kubernetes Role-based Access Control (RBAC).
  • Short-Lived Secrets: Use short-lived Secrets to limit exposure.
  • Additional ServiceAccount Annotations: Enforce specific rules on how Secrets are used in Pods using the kubernetes.io/enforce-mountable-secrets annotation on a ServiceAccount.

Encryption Providers:

When encryption at rest is enabled, Kubernetes uses the configured encryption providers to encrypt secrets before storing them in etcd. Here’s how this works:

  1. KMS Provider: Encrypts secrets using an external Key Management Service (KMS).
  2. AESCBC Provider: Uses AES-CBC (Cipher Block Chaining) mode with a 256-bit key to encrypt secrets.
  3. Secretbox Provider: Uses NaCl’s Secretbox for authenticated encryption, leveraging XSalsa20 and Poly1305.
  4. Identity Provider: Stores data in plaintext without encryption, mainly for testing purposes

Consider External Secret Stores:

  • Services like AWS Secrets Manager or Doppler provide centralized management of secrets.
  • These services offer additional features like rotation, auditing, and fine-grained access control.
  • Integration with Kubernetes simplifies secret management.

Encryption Configuration Example:

To enable encryption at rest, an encryption configuration file must be created and referenced by the Kubernetes API server. Here’s an example:

apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- kms:
name: myKMSProvider
endpoint: unix:///var/run/kms-provider.sock
cachesize: 1000
timeout: 3s
- aescbc:
keys:
- name: key1
secret: <base64-encoded-256-bit-key>
- secretbox:
keys:
- name: key1
secret: <base64-encoded-32-byte-key>
- identity: {}

Verifying Encryption

After setting up encryption, you can verify that secrets are encrypted in etcd by checking the stored data.

For example, using etcdctl to view the secrets in etcd should show encrypted data rather than plaintext.

Remember that while Secrets are base64-encoded, they are stored unencrypted by default. Properly securing your Secrets and following best practices will help protect sensitive information even if etcd is compromised

Conclusion of the question that was asked:

  • Secrets are base64 encoded, which is not secure. If etcd is compromised, secrets can be easily decoded.
  • Encryption at Rest: Provides true encryption for secrets, significantly enhancing security.
    If configured, even if etcd is compromised, secrets remain encrypted and protected.

If you found this guide helpful then do click on 👏 the button.

Follow for more Learning like this 😊

If there’s a specific topic you’re curious about, feel free to drop a personal note or comment. I’m here to help you explore whatever interests you!

Thanks for spending your valuable time learning to enhance your knowledge!

--

--

Nidhi Ashtikar

Experienced AWS DevOps professional with a passion for writing insightful articles.