Kubernetes Secrets Best Practices

Kubernetes Secrets Best Practices

Managing sensitive information is crucial for any application's security and integrity. In Kubernetes, the Secrets resource comes in handy for storing sensitive data like passwords, API tokens, or encryption keys. While using Kubernetes Secrets is a step in the right direction, several best practices should be followed to maximize security. In this post, we'll delve into these best practices.

Table of Contents

  1. Encrypt Secrets at Rest
  2. Use RBAC for Controlled Access
  3. Avoid Environment Variables
  4. Rotate Secrets Regularly
  5. Use Namespaces Wisely

Encrypt Secrets at Rest

By default, Kubernetes Secrets are stored in plaintext in etcd. To enhance security, make sure to encrypt secrets at rest using the available encryption providers.

# apiserver configuration snippet
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
apiServer:
  extraArgs:
    encryption-provider-config: '/etc/kubernetes/pki/secrets.yaml'
# apiserver configuration snippet
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
apiServer:
  extraArgs:
    encryption-provider-config: '/etc/kubernetes/pki/secrets.yaml'

Use RBAC for Controlled Access

RBAC (Role-Based Access Control) should be used to control who can read or modify Secrets. Create focused roles and role bindings.

RoleResourceVerb
secret-adminsecretsget, list, create, update, delete
secret-viewersecretsget, list
# Role for secret-admin
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: secret-admin
rules:
  - apiGroups: ['']
    resources: ['secrets']
    verbs: ['get', 'list', 'create', 'update', 'delete']
# Role for secret-admin
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: secret-admin
rules:
  - apiGroups: ['']
    resources: ['secrets']
    verbs: ['get', 'list', 'create', 'update', 'delete']

Avoid Environment Variables

Exposing secrets as environment variables can lead to unintentional leaks. Instead, mount Secrets as temporary, in-memory volumes.

# Pod configuration to mount secret as a volume
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  volumes:
    - name: my-secret-volume
      secret:
        secretName: my-secret
  containers:
    - name: my-container
      volumeMounts:
        - name: my-secret-volume
          mountPath: '/etc/secret'
# Pod configuration to mount secret as a volume
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  volumes:
    - name: my-secret-volume
      secret:
        secretName: my-secret
  containers:
    - name: my-container
      volumeMounts:
        - name: my-secret-volume
          mountPath: '/etc/secret'

Rotate Secrets Regularly

To minimize the impact of compromised Secrets, you should rotate them regularly. You can automate this using custom scripts or Kubernetes operators.

# Command to patch an existing secret
kubectl patch secret my-secret -p='{"data":{"key": "new_base64_encoded_value"}}'
# Command to patch an existing secret
kubectl patch secret my-secret -p='{"data":{"key": "new_base64_encoded_value"}}'

Use Namespaces Wisely

Use namespaces to segregate Secrets relevant to different parts of your application. This makes it easier to manage access controls and minimize the risk associated with erroneous access or deletion.

# Create secret in a specific namespace
kubectl create secret generic my-secret --from-literal=key=value --namespace=my-namespace
# Create secret in a specific namespace
kubectl create secret generic my-secret --from-literal=key=value --namespace=my-namespace

By following these best practices, you'll be well on your way to securing your Kubernetes Secrets. Take the time to properly configure and manage them to ensure the security and integrity of your applications.