AWS Secrets Manager vs Environment Variables: Where Should Your Application Secrets Live?
Developers often store database passwords, API keys, and JWT secrets in environment variables. Learn when that approach is acceptable and how AWS Secrets Manager provides a safer way to manage sensitive configuration in cloud applications.
AWS Secrets Manager vs Environment Variables: Where Should Your Application Secrets Live?
When building a Spring Boot, Node.js, or Python application, we often need sensitive values such as:
- Database passwords
- API keys
- JWT secrets
- Third-party credentials
- Application tokens
A common approach is to place them in environment variables:
Application
↓
Environment Variables
↓
DATABASE_PASSWORD
API_KEY
JWT_SECRETThis is better than hardcoding secrets directly into source code.
But in a production AWS environment, there is another important question:
Who manages these secrets, and how are they protected?
That's where AWS Secrets Manager becomes useful.
The Problem With Hardcoded Secrets
Consider this example:
String password = "MyDatabasePassword123";It creates several problems.
If this code is pushed to GitHub:
Developer ↓Git Commit ↓GitHub ↓Password exposedEven deleting the password later may not completely solve the problem because it could still exist in Git history.
A better approach is:
String password = System.getenv("DATABASE_PASSWORD");Now the secret isn't stored directly in the source code.
But we still need to manage the environment where that variable is stored.
Environment Variables
Environment variables are useful for development and simpler deployments.
For example:
DATABASE_URL=jdbc:mysql://localhost:3306/appDATABASE_USERNAME=rootDATABASE_PASSWORD=secretYour application reads these values at runtime.
The architecture becomes:
Application ↓Environment Variables ↓Database / APIsAdvantages
- Simple to configure
- Easy to use locally
- Supported by almost every programming language
- Keeps secrets out of source code
But there is a limitation
Environment variables don't automatically provide a centralized secret-management system.
As applications grow, you may have:
ProductionStagingDevelopmentTestingwith different credentials for each environment.
Managing them manually can become difficult.
Enter AWS Secrets Manager
AWS Secrets Manager is designed to securely store and manage sensitive information.
Instead of putting a database password directly into your deployment configuration:
Application ↓AWS Secrets Manager ↓Database PasswordYour application retrieves the secret when it needs it.
A secret might look like:
{ "username": "app_user", "password": "********", "host": "database.example.com", "port": 3306}The application doesn't need to know the password beforehand.
How IAM Fits Into the Picture
One of the most important advantages is that access can be controlled using IAM.
For example:
Spring Boot Application ↓ EC2 Role ↓IAM Permission ↓AWS Secrets Manager ↓Database CredentialsThe EC2 instance can be given permission to retrieve only the required secret.
For example:
{ "Effect": "Allow", "Action": "secretsmanager:GetSecretValue", "Resource": "arn:aws:secretsmanager:region:account:secret:prod/db"}This follows the principle of least privilege.
The application doesn't need permission to access every secret in the AWS account.
Environment Variables vs Secrets Manager
Think about the difference like this:
Environment Variables | AWS Secrets Manager |
|---|---|
Simple configuration | Centralized secret management |
Great for local development | Designed for cloud workloads |
Usually manually managed | AWS-managed service |
Easy to use | Supports IAM-based access |
No built-in secret rotation | Supports secret rotation |
Good for small applications | Useful for production environments |
This doesn't mean environment variables are bad.
A practical approach is:
Local Development ↓Environment Variables
Production AWS ↓AWS Secrets Manager
Example: Spring Boot Application
Instead of:
spring.datasource.password=myPasswordyou can keep the secret outside your source code.
For example:
spring.datasource.url=${DB_URL}spring.datasource.username=${DB_USERNAME}spring.datasource.password=${DB_PASSWORD}During development:
DB_URLDB_USERNAMEDB_PASSWORDcan come from environment variables.
In production, those values can be supplied securely through your AWS deployment architecture.
Don't Put Secrets in Git
One simple rule every developer should follow:
Source Code ↓Git ↓Public/Private Repository
❌ Password ❌ API Key ❌ JWT Secret ❌ Database CredentialsInstead:
Source Code ↓Git
Secret ↓Secret Manager ↓ApplicationAnd if you're using a local
.env file:.env*.envKeep a safe template instead:
.env.exampleFor example:
DB_USERNAME=DB_PASSWORD=JWT_SECRET=This tells other developers what configuration is required without exposing the actual values.
What About Secret Rotation?
Imagine your production database password is:
OldPasswordEventually, you may need to change it.
With manually managed configuration, you might need to:
Change Password ↓Update Configuration ↓Redeploy Application ↓Restart ServicesSecret management services can make this process more structured and can support automated rotation for supported use cases.
That reduces the amount of manual secret handling.
A Simple Production Architecture
A typical architecture could look like:
Users | v Application Load Balancer | v EC2 / ECS / Lambda | +-------+-------+ | | v v Application Secrets Manager | | | v | Database Secret | v RDSThe application retrieves only the secrets it is authorized to access.
A Practical Rule of Thumb
Use environment variables when:
- You're developing locally
- The application is small
- You need simple configuration
- Secrets are injected securely by your deployment platform
Consider AWS Secrets Manager when:
- Multiple environments need different credentials
- You need centralized secret management
- IAM-based access control is important
- Secrets need controlled rotation
- Multiple services need to access shared secrets
The important part isn't simply choosing a tool.
It's designing a system where:
Secrets ↓Are not hardcoded ↓Are not committed to Git ↓Have controlled access ↓Can be rotated ↓Are audited and managed properly
Final Checklist
Before deploying an application to AWS, ask:
- Are secrets removed from source code?
- Is
.envexcluded from Git?
- Are production credentials managed securely?
- Does the application use least-privilege IAM permissions?
- Are development and production secrets separated?
- Can sensitive credentials be rotated?
- Do you know which AWS identity can access each secret?
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article