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
- Encrypt Secrets at Rest
- Use RBAC for Controlled Access
- Avoid Environment Variables
- Rotate Secrets Regularly
- 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.
Role | Resource | Verb |
---|---|---|
secret-admin | secrets | get, list, create, update, delete |
secret-viewer | secrets | get, 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.