🔐 Kubernetes Secrets vs. ConfigMaps – Which One and When? (2025 Guide)
In the world of Kubernetes, separating code from configuration is a best practice. But when it comes to managing settings like environment variables, API tokens, and database credentials — you’ll come across two powerful tools:
- ✅ ConfigMaps
- 🔒 Secrets
They both store configuration, but they are NOT the same — and using them interchangeably could lead to security issues or operational headaches.
Let’s break them down — from basics to best practices — and figure out which one to use, when.
🧠 What’s the Difference Between a ConfigMap and a Secret?
Feature | ConfigMap | Secret |
---|---|---|
Purpose | Store non-sensitive config data | Store sensitive data like passwords, tokens |
Encoding | Stored in plain text | Stored in base64-encoded format |
Access Control | Readable by default | Can be restricted using RBAC |
Encryption | Not encrypted at rest | Can be encrypted at rest (KMS or etcd config) |
Mounting | As files or env vars | Same (files/env), but secured |
Example Use | App name, log level, config toggles | API keys, DB passwords, SSH keys |
🔧 1. What is a ConfigMap?
ConfigMaps are used to store non-sensitive configuration in a key-value format.
✅ Common Use Cases:
- Application name, port, timezone
- Feature flags
- JSON configs
- External URLs
✍️ Example:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_NAME: "myapp"
LOG_LEVEL: "debug"
📦 Usage in Pod:
env:
- name: APP_NAME
valueFrom:
configMapKeyRef:
name: app-config
key: APP_NAME
🔐 2. What is a Secret?
Secrets are used to store sensitive data like passwords, tokens, SSH keys, and TLS certs.
Though they’re base64-encoded by default (⚠️ not encrypted), Kubernetes supports encryption at rest and RBAC to control access.
✅ Common Use Cases:
- DB credentials
- OAuth tokens
- TLS certificates
- Service account keys
✍️ Example:
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
DB_PASSWORD: cGFzc3dvcmQxMjM= # base64 encoded
🔁
echo -n 'password123' | base64
=cGFzc3dvcmQxMjM=
📦 Usage in Pod:
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: DB_PASSWORD
🔐 3. Are Secrets Really Secure?
Yes, if you configure them properly:
Feature | Enabled By |
---|---|
🔒 Encryption at Rest | Set up in EncryptionConfiguration for etcd |
✅ RBAC Access Control | Use Role + RoleBinding to restrict access |
👁️ Audit Logging | Log access to Secrets |
🔄 Automatic Rotation | Use external Secret managers (Vault, AWS Secrets Manager) |
⚠️ By default, Secrets are just base64 — not truly secure.
Always combine them with proper encryption, least-privilege access, and rotation practices.
🔀 4. How to Choose – ConfigMap or Secret?
Scenario | Use |
---|---|
✅ Application name | ConfigMap |
✅ Logging level (debug/info) | ConfigMap |
🔐 API token for 3rd-party service | Secret |
🔐 Database password | Secret |
✅ Feature toggle flags | ConfigMap |
🔐 SSL cert/key pair | Secret (TLS type) |
✅ External API URL | ConfigMap |
🔐 OAuth client secret | Secret |
🧠 Rule of Thumb:
If you wouldn’t share the value on a public forum, put it in a Secret.
🛠️ 5. Best Practices
✅ ConfigMaps:
- Keep unrelated config keys in separate ConfigMaps.
- Use volumes if you want to mount full configs (e.g., YAML or JSON files).
- Version them using labels or annotations.
✅ Secrets:
- Enable encryption at rest for etcd.
- Store only what is absolutely necessary.
- Integrate with external secret managers like:
- HashiCorp Vault
- AWS Secrets Manager
- Azure Key Vault
- Rotate credentials regularly and use initContainers or sidecars for dynamic secrets.
🧩 Bonus: Use Both Together
Yes, you can — and often should — use ConfigMaps and Secrets together in the same pod.
Example:
env:
- name: ENV
valueFrom:
configMapKeyRef:
name: app-config
key: ENV
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: DB_PASSWORD
This keeps your sensitive data isolated, while making general configuration easily manageable.
💼 Real-World Example: A Web App in K8s
Config Item | Source | Reason |
---|---|---|
DB_HOST | ConfigMap | Safe to expose |
DB_PORT | ConfigMap | Non-sensitive |
DB_PASSWORD | Secret | Needs encryption |
API_KEY | Secret | Confidential |
APP_ENV | ConfigMap | Just toggles |
TLS Key/Cert | Secret (TLS type) | Secure by default |
🧠 Final Thoughts
- Use ConfigMaps for what’s safe to expose
- Use Secrets for anything you’d protect with encryption
- Secure your Secrets with RBAC, encryption, and external managers
- Keep everything version-controlled and auditable
Don’t treat your Kubernetes cluster like a vault.
Treat it like an API-driven operating system, and secure it the same way.
Just let me know!
Leave a Reply