Short answer: ConfigMaps and Secrets are both Kubernetes objects that keep configuration out of your container images. Use a ConfigMap for non-sensitive settings such as feature toggles, URLs and log levels. Use a Secret for sensitive values such as passwords, API tokens and TLS certificates. The two work almost the same way, but Secrets get extra handling: they can be encrypted at rest, kept off disk on nodes and locked down with tighter access rules.
If you are new to the platform, start with our guide on what Kubernetes is. This article on ConfigMaps and Secrets assumes you know what a Pod and a Deployment are.
Why Kubernetes Separates Configuration From Code
The twelve-factor app principle says configuration should live outside the code. Baking a database URL or an API key into a Docker image means you need a new image for every environment. It also means anyone who pulls the image can read the values.
ConfigMaps and Secrets solve this. You build one image, then inject different settings for dev, staging and production at runtime. Your image stays generic, and your configuration becomes a versioned, reviewable Kubernetes resource.
What Is a Kubernetes ConfigMap?
A ConfigMap is an API object that stores non-confidential data as key-value pairs. A value can be a short string, like a log level, or a whole file, like an nginx.conf or an application.properties file.
Common things to keep in a ConfigMap:
- Environment names and region settings
- Service URLs and port numbers
- Feature flags and log levels
- Full configuration files for web servers, proxies and apps
A single ConfigMap can hold up to 1 MiB of data. That limit comes from etcd, the key-value store behind the Kubernetes API. If your configuration is larger, split it or move it to a volume or object storage.
What Is a Kubernetes Secret?
A Secret is an API object built for small amounts of sensitive data. It looks almost identical to a ConfigMap, but the values are stored as base64-encoded strings, and Kubernetes treats the object with more care.
Kubernetes ships several built-in Secret types:
- Opaque, the default type for arbitrary user data
- kubernetes.io/tls for a TLS certificate and its private key
- kubernetes.io/dockerconfigjson for pulling images from a private registry
- kubernetes.io/basic-auth and kubernetes.io/ssh-auth for credentials
- kubernetes.io/service-account-token for legacy service account tokens
Secrets share the same 1 MiB limit, so ConfigMaps and Secrets are both meant for small pieces of data.
ConfigMaps vs Secrets: The Key Differences
ConfigMaps and Secrets both store key-value data, and Pods consume them the same way. The differences sit in how Kubernetes stores, protects and exposes them.
Purpose. A ConfigMap is for plain settings. A Secret is for anything that would cause harm if it leaked.
Encoding. ConfigMap values are stored as plain text. Secret values are base64-encoded. Base64 is an encoding, not encryption, so anyone who can read the object can decode it in seconds.
Encryption at rest. By default, ConfigMaps and Secrets are both stored unencrypted in etcd. Cluster admins can turn on encryption at rest for Secrets with an encryption configuration on the API server, ideally backed by a KMS provider. Managed services such as EKS, AKS and GKE offer this as a setting.
Storage on nodes. When a Secret is mounted as a volume, the kubelet keeps it in tmpfs, a memory-backed filesystem, so it is never written to the node's disk. ConfigMaps get no such treatment.
Distribution. The kubelet only sends a Secret to nodes that run a Pod needing it. This limits the blast radius if a node is compromised.
Access control. Because ConfigMaps and Secrets are separate resource types, you can grant broad read access to ConfigMaps while keeping Secrets restricted. Our Kubernetes RBAC guide shows how to scope roles per namespace and per resource.
Visibility in tools. Commands like describe hide Secret values by default, while ConfigMap values print in full. This small detail prevents a lot of accidental leaks in screenshots and logs.
How Pods Use ConfigMaps and Secrets
There are three ways a container can read ConfigMaps and Secrets. Each has trade-offs you should know before you pick one.
- Environment variables. You map one key, or every key, to environment variables in the container. This is simple and works with most apps. The catch: values are read once at startup, so a change needs a Pod restart.
- Mounted volumes. Each key becomes a file inside a directory in the container. Mounted files update automatically when the object changes, usually within a minute or two, depending on the kubelet sync period and cache.
- Command-line arguments. You pass a value from an environment variable into the container's start command. This is handy for tools that only take flags.
One trap catches many teams. If you mount a single file with subPath, that file never receives updates. Use a full directory mount when you need live reloads.
Updating Configuration Without Downtime
Changing ConfigMaps and Secrets does not restart your Pods on its own. You have three good options for rolling out new ConfigMaps and Secrets safely.
- Roll the Deployment. Trigger a rolling restart after the change, so new Pods pick up the new values while old Pods keep serving traffic.
- Use a checksum annotation. Tools like Helm can add a hash of the config to the Pod template. When the config changes, the hash changes and Kubernetes rolls the Pods for you. See our Helm charts guide for how templates work.
- Use immutable objects with versioned names. Mark the object as immutable and create a new one, such as app-config-v2, for every change. Then point the Deployment at the new name. Immutable objects protect you from accidental edits and reduce load on the API server, because the kubelet stops watching them.
The versioned approach pairs well with GitOps, because every config change becomes a reviewed commit and a clean rollout.
Best Practices for Kubernetes Secrets
Plain Kubernetes Secrets are a starting point, not a full security solution. Follow these practices to close the gaps.
- Turn on encryption at rest. Use a KMS provider so the encryption keys live outside the cluster.
- Apply least-privilege RBAC. Only the workloads and people who need a Secret should be able to get, list or watch it. Remember that list access returns full Secret values.
- Never commit raw Secrets to Git. Base64 values in a repository are as good as plain text. Use Sealed Secrets or SOPS to store encrypted versions instead.
- Sync from an external vault. The External Secrets Operator and the Secrets Store CSI Driver can pull values from HashiCorp Vault, AWS Secrets Manager, Azure Key Vault or Google Secret Manager. Our comparison of HashiCorp Vault vs AWS Secrets Manager helps you choose a backend.
- Prefer volume mounts over environment variables. Environment variables can leak through crash dumps, debug endpoints and child processes.
- Rotate regularly. Short-lived credentials limit the damage of any leak.
- Enforce rules with policy. Block Pods that put Secrets in plain environment variables or that run in the wrong namespace. Learn how in our guide to enforcing security policies with OPA.
For a wider view across the whole delivery chain, read our guide to secrets management in DevOps.
Common Mistakes to Avoid
- Putting passwords in a ConfigMap. It feels faster, but it skips every protection Secrets offer.
- Thinking base64 is encryption. It is not. Treat any Secret manifest as sensitive.
- Expecting environment variables to refresh. They do not. Plan a restart or use volume mounts.
- Missing references at startup. If a Pod points to a ConfigMap or Secret that does not exist, it gets stuck in a container-creating state. Our guide on debugging crashing Pods walks through how to spot this.
- Cross-namespace references. A Pod can only use ConfigMaps and Secrets from its own namespace.
- Baking secrets into images. The same rule applies outside Kubernetes. See how to secure secrets in Docker containers.
When to Use Each: A Quick Decision Guide
Choosing between ConfigMaps and Secrets comes down to one question: would it hurt if this value appeared in a public log? If yes, use a Secret. If no, use a ConfigMap.
- Database host and port: ConfigMap
- Database password: Secret
- Feature flags and log level: ConfigMap
- TLS certificate and private key: Secret
- Private registry credentials: Secret
- Full nginx or app config file with no credentials: ConfigMap
If a file mixes both, split it into separate ConfigMaps and Secrets. Keep the non-sensitive part in a ConfigMap and pull the credentials from a Secret.
Conclusion
ConfigMaps and Secrets give you a clean way to run the same image in every environment. ConfigMaps handle everyday settings. Secrets add encoding, memory-only storage on nodes and room for encryption and tight access rules. Neither is a complete vault, so pair Secrets with encryption at rest, RBAC and an external secrets manager for production.
Want hands-on practice with ConfigMaps and Secrets, Helm and GitOps? Explore the DevOps courses at PaperLive Learning and build real projects you can show employers.


