Kubernetes Secrets Management: Secure Your Container Secrets
Complete guide to managing secrets in Kubernetes. Learn etcd encryption, RBAC, secret rotation, and integrations with vault and external secret operators.
Kubernetes Secrets Management: Secure Your Container Secrets
Kubernetes is where modern applications run. It's also where many teams struggle with secrets management.
By default, Kubernetes stores secrets in etcd—unencrypted. That's a disaster waiting to happen.
The Kubernetes Secrets Problem
By default:
- Secrets are base64-encoded (not encrypted!)
- Stored in etcd in plain text
- Accessible to any pod with RBAC permissions
- No audit trail
- No rotation mechanism
Creating Kubernetes Secrets
Method 1: From Command Line
kubectl create secret generic db-credentials \
--from-literal=username=admin \
--from-literal=password=secret123
Method 2: From YAML
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque
data:
username: YWRtaW4= # base64: admin
password: c2VjcmV0MTIz # base64: secret123
Method 3: From .env File
kubectl create secret generic app-secrets --from-env-file=.env
Using Secrets in Pods
Mounting as Environment Variables
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- name: app
image: myapp:latest
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: db-credentials
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
Mounting as Volumes
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- name: app
image: myapp:latest
volumeMounts:
- name: secrets
mountPath: /etc/secrets
readOnly: true
volumes:
- name: secrets
secret:
secretName: db-credentials
Securing Kubernetes Secrets
Enable etcd Encryption
# /etc/kubernetes/encryption-config.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: <base64-encoded-32-byte-secret>
- identity: {}
Implement RBAC
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list"]
resourceNames: ["db-credentials"] # Limit to specific secret
External Secrets Operator
For production, use External Secrets Operator to sync secrets from XtraSecurity, Vault, or AWS:
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: vault-backend
spec:
provider:
vault:
server: "https://vault.example.com"
path: "secret"
Secrets Rotation in Kubernetes
Never use static secrets. Rotate frequently:
# Rotate database password
kubectl patch secret db-credentials -p \
'{"data":{"password":"'$(echo -n newpassword|base64)'"}}'
Best Practices
- Enable etcd encryption at rest
- Use RBAC to limit secret access
- Don't commit secrets to Git
- Use External Secrets Operator for production
- Audit secret access with logging
- Rotate secrets regularly (every 30 days)
- Use read-only mounts for secret volumes
- Never use default namespace for secrets
Conclusion
Kubernetes secrets require encryption, RBAC, and regular rotation.
About the Author
OM Salunke is a security engineer with expertise in DevOps, cloud infrastructure, and secrets management. He has helped enterprise teams secure their infrastructure on AWS, Google Cloud, and Azure.