
AWS Secrets Manager Explained: Stop Hard-Coding Passwords and API Keys
A beginner-friendly guide to AWS Secrets Manager and how applications can securely store, retrieve, rotate, and manage database passwords, API keys, and other sensitive credentials without putting secrets directly into source code.
🔐 AWS Secrets Manager Explained: Stop Hard-Coding Passwords and API Keys
While learning AWS, I noticed a problem that can easily be overlooked:
Where should an application store passwords, API keys, and other sensitive credentials?
A beginner might write something like this:
1
DATABASE_PASSWORD = "MySuperSecretPassword123"It works.
But it's a terrible habit.
Why?
Because that password could end up in:
- Source code
- Git history
- GitHub repositories
- Logs
- Deployment packages
- Screenshots
- Shared files
So I started exploring a better approach:
🔐 AWS Secrets Manager
Instead of putting secrets inside my application, I can store them securely in AWS Secrets Manager and allow my application to retrieve them when needed.
My new mental model is:
1
2
3
4
5
6
7
8
Application
│
│ Request secret
▼
AWS Secrets Manager
│
▼
Secret ValueThe application doesn't need to hard-code the password.
🧠 What Is AWS Secrets Manager?
AWS Secrets Manager is a service designed to help securely store and manage sensitive information.
Examples include:
1
2
3
4
5
Database passwords
API keys
Application credentials
OAuth tokens
Other sensitive configurationInstead of:
1
password = "secret123"I can store the secret in AWS and retrieve it programmatically.
This separates:
1
2
3
Application Code
+
Sensitive Credentialswhich is a much better security model.
🚨 Why Hard-Coding Secrets Is Dangerous
Imagine I create a Python application:
1
import requestsAPI_KEY = "abc123secret"response = requests.get( "https://api.example.com/data", headers={ "Authorization": API_KEY })Everything looks fine.
Then I push the code to GitHub.
Now the secret may be exposed.
Even if I delete the line later, the credential might still exist in Git history or other places where it was copied.
The safer architecture is:
1
2
3
4
5
6
7
Python Application
│
▼
Secrets Manager
│
▼
API KeyNow the secret isn't sitting directly inside my application source code.
🏗️ A Simple Architecture
Suppose I have an application running on EC2.
Instead of:
1
2
3
4
5
EC2
│
└── Application
│
└── Password inside code ❌I can build:
1
2
3
4
5
6
7
8
9
10
11
12
EC2
│
Application
│
│
IAM Role
│
▼
Secrets Manager
│
▼
DatabaseThe application gets permission to retrieve the secret through AWS Identity and Access Management.
This is important because I don't want every AWS resource to automatically have access to every secret.
🔑 IAM + Secrets Manager
This connects directly to the IAM concepts I learned earlier.
Imagine my application runs on an EC2 instance.
I can use an IAM role to grant the application permission to retrieve a particular secret.
Conceptually:
1
2
3
4
5
6
7
8
9
10
11
EC2
│
▼
IAM Role
│
│ Permission
▼
Secrets Manager
│
▼
Specific SecretThis is much better than putting AWS access keys inside the application.
The principle I'm learning is:
Use IAM to control who or what can access a secret.
🐍 Retrieving a Secret With Python
AWS SDK for Python is called Boto3.
A simplified example looks like this:
1
import boto3import jsonclient = boto3.client("secretsmanager")response = client.get_secret_value( SecretId="my-database-secret")secret = json.loads(response["SecretString"])username = secret["username"]password = secret["password"]print("Secret retrieved successfully")The application can now retrieve the credentials when it needs them.
The password doesn't have to be written directly into the Python source code.
🗄️ Example Database Secret
Imagine I create a secret containing:
1
2
3
4
5
6
{
"username": "appuser",
"password": "StrongPasswordHere",
"host": "database.example.internal",
"port": 5432
}My application can retrieve this information from Secrets Manager.
The application code can then use:
1
2
3
4
username
password
host
portwithout storing those values directly in the source code.
🔄 What Is Secret Rotation?
One of the features that makes Secrets Manager especially interesting is secret rotation.
Imagine a database password is:
1
OldPasswordIf the password never changes, an attacker who somehow obtains it could potentially use it for a long time.
With rotation, credentials can be changed periodically.
Conceptually:
1
2
3
4
5
6
7
Old Credential
│
▼
Rotation Process
│
▼
New CredentialThis reduces the lifetime of a compromised credential.
For supported scenarios, Secrets Manager can automate rotation workflows.
⏰ Why Rotation Matters
Imagine an organization has 100 applications.
If every application uses a permanent password, changing that password manually can be difficult.
Instead:
1
2
3
4
5
6
7
8
9
Secrets Manager
│
▼
Credential Rotation
│
├── Application
├── Database
├── Service
└── Other ConsumersCentralized secret management can make credential lifecycle management much easier.
🆚 Secrets Manager vs Environment Variables
A common approach in applications is:
1
2
Environment Variable
DATABASE_PASSWORD=secret123Environment variables can be useful for configuration, but sensitive credentials still need careful handling.
Secrets Manager provides dedicated capabilities for managing secrets, including access control and rotation support.
A useful mental model is:
1
2
3
4
5
6
7
Normal Configuration
↓
Environment / Config
Sensitive Credentials
↓
Secrets ManagerThe exact implementation depends on the application.
🆚 Secrets Manager vs Hard-Coded Secrets
Here's the difference I now keep in mind:
| Approach | Security | Rotation | Central Management |
|---|---|---|---|
| Hard-coded password | ❌ Poor | ❌ Manual | ❌ |
| Plain configuration file | ⚠️ Risky | ❌ Manual | ❌ |
| Environment variable | ⚠️ Depends on handling | ❌ Usually manual | ❌ |
| Secrets Manager | ✅ Designed for secrets | ✅ Supported | ✅ |
The goal isn't simply:
"Hide the password."
The goal is:
Manage credentials throughout their entire lifecycle.
🔐 Encryption
Secrets stored in Secrets Manager are encrypted.
AWS Key Management Service (KMS) can be used as part of the encryption model.
A simplified view is:
1
2
3
4
5
6
7
8
9
10
Application
│
▼
Secrets Manager
│
▼
Encrypted Secret
│
▼
KMSThe important concept for me is that sensitive data shouldn't simply sit around as readable text without appropriate protection.
🧑💻 Secrets in a Serverless Application
I can also use Secrets Manager with Lambda.
Imagine the architecture:
1
2
3
4
5
6
7
8
9
10
11
API Gateway
│
▼
Lambda
│
│ IAM Permission
▼
Secrets Manager
│
▼
Database/APILambda doesn't need to contain the password directly.
Instead, it can retrieve the required secret securely.
This makes Secrets Manager a useful building block for serverless applications too.
🌐 Example: Lambda + Database
Imagine I have:
1
2
3
4
5
6
7
API Gateway
│
▼
Lambda
│
▼
DatabaseThe Lambda function needs database credentials.
Instead of:
1
DB_PASSWORD = "password123"I can use:
1
2
3
4
5
6
7
8
9
10
Lambda
│
▼
IAM Execution Role
│
▼
Secrets Manager
│
▼
Database CredentialsThis creates a much cleaner architecture.
🛡️ Least Privilege
Here's where my IAM learning becomes useful again.
Suppose my Lambda function only needs access to:
1
my-production-db-secretI shouldn't automatically give it permission to retrieve:
1
every-secret-in-the-accountInstead, I want the permission to be as narrow as practical.
Conceptually:
1
2
3
4
5
6
7
Lambda
│
└── IAM Role
│
└── Can retrieve
│
└── Specific SecretThis follows the principle of least privilege.
⚠️ Don't Log Secrets
Moving secrets into Secrets Manager doesn't automatically make an application secure.
I still need to make sure my application doesn't accidentally log them.
For example, I should avoid:
1
print(password)or:
1
logger.info("Database credentials: %s", secret)A secure application should retrieve sensitive information without unnecessarily exposing it in logs.
This is particularly important because logs can be retained and accessed by other systems or users.
💡 What If a Secret Is Accidentally Exposed?
Suppose I discover that an API key was accidentally committed to GitHub.
The answer isn't simply:
"I'll delete the GitHub file."
The credential itself should be treated as compromised.
A better response is:
1
2
3
4
5
6
7
8
9
10
11
12
13
Secret exposed
│
▼
Revoke / Rotate credential
│
▼
Update secret store
│
▼
Investigate exposure
│
▼
Improve security controlsThis is an important security mindset:
A secret that has been exposed should be considered compromised.
🔥 Secrets Manager in a Real Architecture
Now I can combine many of the AWS concepts I've learned.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
🌍 User
│
▼
API Gateway
│
▼
Lambda
│
┌─────────┴─────────┐
│ │
▼ ▼
DynamoDB Secrets Manager
│
▼
Database/APIAnd IAM controls access:
1
2
3
4
5
6
7
8
9
IAM
│
┌────────────┴────────────┐
▼ ▼
Lambda EC2
│ │
└──────────┬──────────────┘
▼
Secrets ManagerNow I'm starting to see security as something that is built into the architecture rather than added at the end.
⚠️ Common Beginner Mistakes
❌ Mistake 1: Hard-coding passwords
Avoid putting credentials directly in source code.
❌ Mistake 2: Committing .env files
A
.env file can still contain sensitive credentials.Don't assume it's safe just because it's outside your main code.
❌ Mistake 3: Giving broad IAM permissions
Don't give an application access to every secret when it only needs one.
❌ Mistake 4: Logging secrets
Never print passwords, API keys, tokens, or other sensitive values unnecessarily.
❌ Mistake 5: Forgetting rotation
A secure credential also needs a sensible lifecycle.
❌ Mistake 6: Thinking Secrets Manager solves everything
It protects and manages secrets, but the application still needs proper IAM, logging, network, and security practices.
🧠 The Biggest Lesson
Before learning Secrets Manager, I mostly thought:
"I need a password, so I'll put it somewhere my application can read it."
Now I think:
"How can my application securely obtain the credential without owning the credential inside its source code?"
That's a much better cloud-security question.
My mental model is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Don't do this:
Application
│
└── Hard-coded Secret ❌
Do this:
Application
│
▼
IAM
│
▼
Secrets Manager
│
▼
Secret🚀 Final Takeaway
AWS Secrets Manager taught me that security isn't only about firewalls and network rules.
It's also about:
🔐 Credential storage
🧑💻 Application access
🔄 Secret rotation
🛡️ Least privilege
📝 Avoiding secret exposure
The architecture I now want to build is:
1
2
3
4
5
6
7
8
9
10
Application
│
▼
IAM
│
▼
Secrets Manager
│
▼
Secure CredentialsInstead of putting secrets inside my code, I can let AWS manage them separately from the application logic.
That's a small architectural change, but it can make a huge difference in how securely an application is designed.
Don't just make your application work. Make sure it knows how to handle secrets safely. 🔐☁️
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article