AWS Builder Center

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_SECRET
This 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 exposed
Even 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/app
DATABASE_USERNAME=root
DATABASE_PASSWORD=secret
Your application reads these values at runtime.
The architecture becomes:
Application
↓
Environment Variables
↓
Database / APIs

Advantages

  • 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:
Production
Staging
Development
Testing
with 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 Password
Your 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 Credentials
The 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=myPassword
you 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_URL
DB_USERNAME
DB_PASSWORD
can 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 Credentials
Instead:
Source Code
↓
Git

Secret
↓
Secret Manager
↓
Application
And if you're using a local  .env  file:
.env
*.env
Keep a safe template instead:
.env.example
For 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:
OldPassword
Eventually, you may need to change it.
With manually managed configuration, you might need to:
Change Password
↓
Update Configuration
↓
Redeploy Application
↓
Restart Services
Secret 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
RDS
The 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  .env  excluded 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?
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article