Production-ready Kubernetes Part 8 - Secrets, Vaults, and the Real Cost of Leaked Credentials
Secrets, Vaults, and the Real Cost of Leaked Credentials
3/19/2026
Kubernetes makes it deceptively easy to store sensitive data.
A simple command like:
echo -n "password" | base64
can quickly become a Kubernetes Secret:
apiVersion: v1kind: Secretmetadata:name: db-credentialstype: Opaquedata:password: cGFzc3dvcmQ=
And suddenly, your application can access credentials without hardcoding them.
Simple, right?
Unfortunately, secret management in production is rarely that simple.
If you run a large enough system long enough, credentials will eventually leak through:
- logs
- debugging output
- CI pipelines
- crash dumps
- misconfigured RBAC
- compromised nodes
At that point, your secret management architecture determines the blast radius.
In Kubernetes, teams typically evolve through three patterns:
- 1️⃣ Environment variables
- 2️⃣ Mounted secret files
- 3️⃣ External vault systems
Each approach has different tradeoffs in security, operational complexity, and developer experience.
Understanding when each pattern is acceptable — and when it becomes dangerous — is key to running Kubernetes in production.
1️⃣ Kubernetes Secrets Are Not Really "Secret"
Before discussing patterns, it's important to understand something many engineers misunderstand.
Kubernetes Secrets are not encrypted by default.
They are simply base64-encoded values stored in etcd.
Example:
data:password: cGFzc3dvcmQ=
This is encoding, not encryption.
Anyone with access to the cluster API can decode it instantly:
kubectl get secret db-credentials -o jsonpath='{.data.password}' | base64 --decode
If a malicious actor gains:
- access to the API server
- permissions via RBAC
- or access to etcd backups
they can retrieve every secret stored in the cluster.
Mitigations exist:
- Encryption at rest for etcd
- RBAC restrictions
- audit logging
- external secret managers
But it's important to understand:
Kubernetes Secrets are a distribution mechanism, not a full secret management system.
2️⃣ Environment Variables — The Quick & Dirty Pattern
The simplest way to inject secrets into an application is through environment variables.
Example:
apiVersion: apps/v1kind: Deploymentmetadata:name: apispec:template:spec:containers:- name: apiimage: my-api:latestenv:- name: DB_PASSWORDvalueFrom:secretKeyRef:name: db-credentialskey: password
The application simply reads the environment variable:
db_password = os.getenv("DB_PASSWORD")
This pattern is popular because:
- easy for developers
- supported by every language
- easy to configure in Kubernetes
But environment variables have serious leakage risks.
Secrets can appear in:
- process listings
- crash dumps
- debugging logs
- application error output
- CI/CD pipeline logs
- container inspection tools
Example:
kubectl exec -it pod -- printenv
This can expose all environment variables.
When environment variables are acceptable
Environment variables are fine for:
- non-sensitive configuration
- feature flags
- internal service endpoints
- low-risk tokens
Example:
CACHE_TTL=60FEATURE_FLAG_NEW_UI=trueSERVICE_ENDPOINT=https://internal-api
When they should be avoided
Avoid environment variables for:
- database passwords
- API tokens
- private keys
- encryption keys
If a credential leak would trigger a security incident, environment variables are not the right solution.
3️⃣ Mounted Secrets — A Safer Default
A more secure approach is mounting secrets as files.
Example Kubernetes configuration:
volumes:- name: db-secretsecret:secretName: db-credentialscontainers:- name: apiimage: my-api:latestvolumeMounts:- name: db-secretmountPath: /secretsreadOnly: true
Inside the container, Kubernetes creates files:
/secrets/password
The application reads the file:
with open("/secrets/password") as f:db_password = f.read().strip()
Kubernetes mounts these secrets via tmpfs, meaning:
- stored in memory
- not written to disk
Why mounted secrets are safer
Mounted secrets reduce several risks:
- not exposed in process trees
- less likely to appear in logs
- easier to restrict filesystem access
Another benefit:
Applications can watch files for changes.
This allows secret rotation without restarting pods.
Example patterns:
- Nginx reloading TLS certificates
- apps watching configuration files
- sidecars updating credentials
Limitations
Mounted secrets still have limitations:
- secrets still exist in etcd
- secrets still accessible via Kubernetes API
- rotation is often manual
- auditing is limited
For many organizations, this is good enough.
But for regulated environments, it may not be.
4️⃣ External Vaults — Centralized Secret Management
For organizations with strong security requirements, external vault systems provide a more robust solution.
Examples include:
- HashiCorp Vault
- AWS Secrets Manager
- Azure Key Vault
- Google Secret Manager
These systems provide capabilities Kubernetes lacks:
- automatic secret rotation
- dynamic credentials
- centralized access policies
- full audit trails
- secret leasing and expiration
Example: dynamic database credentials with Vault.
Instead of storing a static password, Vault generates temporary credentials:
username: app-2981password: xF32kQ91ttl: 1 hour
When the credential expires, it becomes invalid automatically.
This drastically reduces the blast radius of credential leaks.
The tradeoff: operational complexity
Vault systems introduce new operational responsibilities:
- running or integrating the vault
- configuring authentication
- managing policies
- integrating with Kubernetes
For small systems, this complexity may not be worth it.
But for large platforms, it often becomes necessary.
5️⃣ The Bridge — Kubernetes Operators
External vaults are powerful, but they need integration with Kubernetes.
This is where operators come in.
Popular tools include:
- External Secrets Operator (ESO)
- Bank-Vaults
- Secrets Store CSI Driver
Example using External Secrets Operator:
apiVersion: external-secrets.io/v1beta1kind: ExternalSecretmetadata:name: db-credentialsspec:refreshInterval: 1hsecretStoreRef:name: aws-secretskind: SecretStoretarget:name: db-credentialsdata:- secretKey: passwordremoteRef:key: production/db/password
The operator:
- fetches secrets from the external vault
- creates or updates Kubernetes Secrets
- keeps them synchronized
This allows teams to combine:
- vault security
- Kubernetes-native consumption
without manually copying secrets.
Conclusion
There is no single correct way to manage secrets in Kubernetes.
Instead, the right solution depends on:
- the sensitivity of your credentials
- your security requirements
- your operational maturity
- your compliance constraints
A common maturity path looks like this:
Early stage systems
Environment variables for simple configuration.
Growing platforms
Mounted secrets for better isolation.
Security-critical environments
External vaults with automated rotation.
The key insight is that secret management defines your blast radius.
When a credential eventually leaks — and one eventually will — your architecture determines how painful that incident becomes.
Actionable Steps
Step 1 — Audit your current secrets
Identify:
- where secrets are stored
- how they are injected into applications
- which credentials are most sensitive
Step 2 — Reduce environment variable usage
Move sensitive credentials away from environment variables and into mounted secrets.
Step 3 — Enable encryption at rest
Ensure Kubernetes etcd encryption is enabled for secrets.
Step 4 — Implement RBAC restrictions
Restrict who can:
- list secrets
- read secrets
- modify secrets.
Step 5 — Evaluate external vaults
If your system requires:
- strict auditing
- automated rotation
- compliance controls
introduce a dedicated secret management platform.
Related Posts
Production-ready Kubernetes Series:
- Part 1 - Observability Foundations
- Part 2 - Observability Stacks
- Part 3 - Availability - Graceful Termination
- Part 4 - Availability - Kubernetes Components
- Part 5 - Cost Optimization
- Part 6 - Alternatives - Tradeoff Analysis
- Part 7 - Security - Hardening
- Part 8 - Security - Secrets
- Part 9 - Networking - Resources
- Part 10 - Networking - Service Mesh
- Part 11 - Multi-region & Disaster Recovery