Once configuration is separated from the application image, the next obvious question appears quickly: where should passwords, tokens, and other sensitive values go?
That is where Secret comes in. Secret is one of the standard Kubernetes resources for delivering sensitive values into Pods.
This post covers three things.
- what a Secret is
- how it differs from ConfigMap
- how to inject it through environment variables or mounted files
The key idea is this: Secret is the resource boundary for values that become risky when exposed.
What a Kubernetes Secret is
A Secret stores sensitive values such as passwords, API tokens, or private keys so they can be supplied to Pods in a structured way.
Common examples include:
- database passwords
- external API tokens
- TLS private keys
- registry credentials
So Secret is part of configuration, but specifically the sensitive part of it.
How Secret differs from ConfigMap
At first, both resources can look like simple key-value stores.
- ConfigMap: general configuration
- Secret: sensitive values
A simple mental split is:
- ConfigMap: log level, API address, feature flags
- Secret: database password, access token, private key
Technically, you can place strings in either place, but operationally and from a security perspective, sensitive values belong in Secret.
A simple Secret example
apiVersion: v1
kind: Secret
metadata:
name: app-secret
type: Opaque
stringData:
DB_PASSWORD: super-secret-password
API_TOKEN: my-token
For learning, stringData is the easiest format to read and write. Kubernetes handles the internal representation after that.
In real systems, the larger question becomes how Secrets are stored in Git or integrated with external secret managers. But the beginner lesson comes first: sensitive values should live behind a different operational boundary than normal config.
Injecting Secret as environment variables
This is one of the most common patterns.
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: app-secret
key: DB_PASSWORD
This makes the secret available as the DB_PASSWORD environment variable inside the container.
If the application already reads most config from environment variables, this is often the simplest way to start.
Mounting Secret as files
Some applications need secrets as files, not just env vars. Certificates and private keys are the most common examples.
This pattern fits well when the application or library expects:
- TLS certificate files
- key files
- credentials at a file path
That is why Secret volumes appear often in HTTPS and identity-related setups.
Does Secret automatically mean strong security
This part matters. Secret is the correct resource type for sensitive values, but it does not mean every security problem is solved automatically.
You still need to care about things like:
- who can read Secrets
- whether etcd encryption is enabled
- how values are stored in Git
- whether logs or debug output expose them
So Secret is an important boundary, but not the end of the security story.
Common mistakes
1. Committing real secret values directly to Git
This is common in beginner examples, but real sensitive values should usually not be stored that way.
2. Injecting secrets and then printing them in logs
Applications often leak secrets through debug output more easily than people expect.
3. Treating Secret and ConfigMap as interchangeable
If the value is sensitive, the safer default is to treat it as a Secret.
A good beginner exercise
- create a Secret for a database password
- inject it into an app as an environment variable
- compare that with storing the same value in a ConfigMap
- try a certificate or key file mount example
That exercise helps Secret feel less like a generic store and more like an operational boundary for sensitive data.
FAQ
Q. Is a Secret secure just because it is base64 encoded?
No. Base64 is closer to encoding than encryption. The larger security setup still matters.
Q. Can I still use environment variables for secrets?
Yes, but you should think carefully about exposure paths and logging behavior.
Q. Is Secret worth using in a small project?
If a value is sensitive, separating it early is usually a good habit regardless of scale.
Read Next
- If you want to compare this with normal runtime settings, pair it with Kubernetes ConfigMap Guide.
- If you want to understand how configuration boundaries map to environment boundaries, continue with Kubernetes Namespace Guide.
While AdSense review is pending, related guides are shown instead of ads.
Start Here
Continue with the core guides that pull steady search traffic.
- Middleware Troubleshooting Guide: Redis vs RabbitMQ vs Kafka A practical middleware troubleshooting guide for developers covering when to reach for Redis, RabbitMQ, or Kafka symptoms first, and which problem patterns usually belong to each tool.
- Kubernetes CrashLoopBackOff: What to Check First A practical Kubernetes CrashLoopBackOff troubleshooting guide covering startup failures, probe issues, config mistakes, and what to inspect first.
- Kafka Consumer Lag Increasing: Troubleshooting Guide A practical Kafka consumer lag troubleshooting guide covering what lag usually means, which consumer metrics to check first, and how poll timing, processing speed, and fetch patterns affect lag.
- Kafka Rebalancing Too Often: Common Causes and Fixes A practical Kafka troubleshooting guide covering why consumer groups rebalance too often, what poll timing and group protocol settings matter, and how to stop rebalances from interrupting useful work.
- Docker Container Keeps Restarting: What to Check First A practical Docker restart-loop troubleshooting guide covering exit codes, command failures, environment mistakes, health checks, and what to inspect first.
While AdSense review is pending, related guides are shown instead of ads.