What is the difference between a ConfigMap and a Secret in K8s?
ConfigMaps and Secrets both decouple configuration from container images, but they differ in their intended sensitivity, storage handling, and access controls.
A **ConfigMap** stores arbitrary non-sensitive key-value pairs or entire config files — things like feature flags, log levels, or application properties. The data is stored as plain UTF-8 text in etcd. There is no additional encoding; what you put in is what you read out. ConfigMaps can be consumed as environment variables, command-line arguments, or files mounted into a pod via a projected volume.
A **Secret** is designed for sensitive data: passwords, TLS certificates, API tokens, and SSH keys. By default, Secret values are base64-encoded in the Kubernetes API — this is *encoding*, not *encryption*. The values are trivially reversible with `base64 -d`. The real security comes from layering additional controls: enabling **encryption at rest** in the API server (`EncryptionConfiguration` with an AES-GCM or KMS provider), tightening RBAC so only the pods and service accounts that need a Secret can `get` it, and using external secret managers (Vault, AWS Secrets Manager) via operators like External Secrets Operator.
Kubernetes applies some extra protections to Secrets by default: they are stored in a `tmpfs` (memory-backed) volume on the node rather than written to disk, and they are only sent to nodes that have a pod requesting them. However, anyone with `kubectl get secret` permission on the namespace can read all Secrets there, so RBAC hygiene is critical.
In practice, the injection patterns are identical: `envFrom`, `env.valueFrom.secretKeyRef`, or a `volume` mount. For Secrets in volumes, Kubernetes can also update the mounted file automatically when the Secret changes without restarting the pod, but environment variable injection requires a pod restart to pick up changes — an important operational difference for both resource types.
The key interview point is: base64 is not security. Treat Secrets as a namespace-level access-control primitive, not an encryption primitive, and back them with real encryption and least-privilege RBAC.
| Aspect | ConfigMap | Secret |
|---|---|---|
| Use case | Non-sensitive config, feature flags | Passwords, tokens, TLS certs |
| Storage encoding | Plain UTF-8 | Base64 (not encrypted by default) |
| Encryption at rest | Not applicable | Optional via EncryptionConfiguration or KMS |
| Node storage | Written to disk | tmpfs (memory-backed) volume |
| RBAC sensitivity | Standard | Should be tightly restricted |
| Auto-update in volume mounts | Yes (with kubelet sync) | Yes (with kubelet sync) |
| Max size | 1 MiB | 1 MiB |
Correctly identifies the sensitivity distinction and base64 encoding. May not explain that base64 is not encryption or miss the RBAC/encryption-at-rest angle.
Explains base64 vs. encryption explicitly, names encryption-at-rest mechanisms, discusses RBAC as the real access-control layer, and mentions external secret managers or the tmpfs node storage difference.
Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.
Get Graded — Free Assessment