Put non-confidential settings in a ConfigMap and credentials in a Secret. Neither is a vault. A ConfigMap offers no secrecy at all, and a Secret is stored unencrypted in etcd by default unless you enable encryption at rest. Sort by sensitivity first, then add access controls.
What each object is for
The Kubernetes documentation describes a ConfigMap as an API object for non-confidential data in key-value pairs. Pods can consume it as environment variables, command-line arguments or files in a volume. It lets you keep environment-specific settings out of the container image.
It also carries a caution: a ConfigMap does not provide secrecy or encryption. If the data is confidential, use a Secret or other tools.
A Secret holds a small amount of sensitive data such as a password, token or key. The docs describe Secrets as similar to ConfigMaps but intended for confidential data.
A sorting rule for each value
Ask three questions about each value.
Would it hurt if a stranger read it? A database hostname usually would not. A database password would. The first goes in a ConfigMap, the second in a Secret.
Does it grant access to something? Tokens, keys, certificates and connection strings with passwords grant access. They are Secrets.
Does it change per environment? Both objects handle that. The twelve-factor idea of separating config from code applies to both.
What a Secret does not give you
The docs are direct that Secrets are, by default, stored unencrypted in the API server's data store. Anyone with API access can retrieve or modify a Secret, and so can anyone with access to etcd.
They add a point that surprises teams: anyone authorized to create a Pod in a namespace can read any Secret in that namespace, including indirect access such as creating a Deployment. So Pod creation rights are secret read rights.
The minimum steps the docs list
For safe use, the documentation says to take at least these steps: enable encryption at rest for Secrets, set up RBAC with least-privilege access to Secrets, restrict Secret access to specific containers, and consider external secret store providers.
Our post on the Kubernetes Secrets checklist goes through these in more detail.
Two other facts worth knowing
ConfigMaps are not designed for large data. The docs cap the stored data at 1 MiB.
You can mark a ConfigMap immutable, available since v1.19. For settings that should never drift once deployed, immutability turns an accidental edit into an error and forces a new object and a rollout instead.
A worked example
Take a service with five settings: a log level, a feature timeout, the database hostname, the database password and a third-party API token. The first three go in a ConfigMap. The last two go in a Secret, mounted to only the container that needs them. The database hostname alone gives an attacker little. The password and token do.
Review the split when settings are added. A value that starts harmless can become sensitive when someone appends credentials to a URL.
Common mistakes
- Putting a password in a ConfigMap because it was easier to read in the manifest.
- Storing a non-secret in a Secret, which clutters access reviews with noise.
- Assuming base64 in a Secret manifest is protection. It is encoding.
- Granting broad Deployment rights in a namespace that holds production Secrets.
Quick check
Can I put a database password in a ConfigMap?
No. The docs say a ConfigMap provides no secrecy, so use a Secret and add encryption at rest and tight RBAC.
Does using a Secret mean the value is encrypted?
Not by default. Kubernetes stores Secrets unencrypted in etcd unless you enable encryption at rest.
Sources
Last reviewed: 19 October 2026.