Manage configuration and secrets safely in Java services using environment variables, external config and vault-style secret injection patterns.
On this page
Why Configuration Is a Security Boundary
Configuration defines:
- database credentials
- API keys
- signing keys
- feature flags
- environment behavior
If configuration management is weak:
- secrets leak into Git
- wrong environment variables reach production
- staging connects to production database
- secret rotation becomes impossible
Configuration errors are silent production risks.
Incident Scenario: Production Database Wiped From Staging
A staging deployment accidentally pointed to production database.
Reason:
A misconfigured environment variable overrode intended profile setting.
One cleanup script executed.
Production data was deleted.
Root cause:
No strict environment separation.
No config validation at startup.
Principle: Same Artifact, Different Configuration
Never build separate artifacts for:
- dev
- staging
- production
Build once.
Inject configuration externally.
If logic differs by profile, drift is guaranteed.
Environment Variables as Baseline
Environment variables are:
- process-scoped
- easily injected by container orchestrators
- not committed to source control
Use env vars for:
- DB URL
- credentials
- API keys
- feature flags
Do not hardcode secrets in:
- application.yml
- application.properties
- Java source files
Configuration Precedence Awareness
Spring Boot config precedence matters:
- command line
- environment variables
- application files
- defaults
You must know what overrides what.
Log effective configuration on startup (excluding secrets).
Fail fast if required variables are missing.
Anti-Pattern: Committing Secrets to Git
Common failures:
- AWS keys committed accidentally
- JWT signing key stored in repository
- database password in test config
Even if repository is private, this is unacceptable.
Secrets leak through:
- forks
- backups
- CI logs
- developer machines
Use secret scanning in CI.
Secret Injection Patterns
Production patterns include:
- environment variables injected by orchestrator
- mounted secret files (Kubernetes secrets)
- sidecar injection
- secret managers (Vault-like systems)
Application should:
- read secret from env or file
- not log it
- fail if missing
Do not fetch secrets via HTTP on every request.
Fetch once at startup or via controlled refresh.
Secret Rotation Strategy
Secrets must be rotatable without full redeploy when possible.
Approaches:
- short-lived credentials (recommended)
- dual-key validation during rotation window
- reloadable config via refresh endpoints (careful with security)
If your system cannot rotate a key without downtime, it is fragile.
Logging and Secret Leakage
Never log:
- full connection strings
- Authorization headers
- JWT tokens
- private keys
- password values
Mask values in:
- exception messages
- startup logs
- debug dumps
Example:
Instead of logging full JDBC URL, log host and database name only.
Configuration Validation at Startup
Fail fast if:
- required secrets are missing
- values are malformed
- environment is inconsistent
Better to crash at startup than misbehave silently.
Immutable Infrastructure Principle
Containers should:
- not write secrets to disk permanently
- not persist modified config inside image
- not rely on manual SSH edits
Configuration must be declarative and reproducible.
Checklist
- Build one artifact for all environments
- Inject secrets via environment or secret manager
- Never commit secrets to source control
- Understand config precedence and overrides
- Fail fast on missing or malformed config
- Mask secrets in logs and error messages
- Plan secret rotation from day one
- Use short-lived credentials when possible
- Avoid environment-specific logic in code
Configuration is not just wiring.
It defines security posture and operational stability.