AWS Builder Center
AWS Secrets Manager Explained: Stop Hard-Coding Passwords and API Keys

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 Value
The 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 configuration
Instead of:
1
password = "secret123"
I can store the secret in AWS and retrieve it programmatically.
This separates:
1
2
3
Application Code
+
Sensitive Credentials
which 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 Key
Now 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
│
▼
Database
The 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 Secret
This 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
port
without 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
OldPassword
If 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 Credential
This 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 Consumers
Centralized 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=secret123
Environment 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 Manager
The exact implementation depends on the application.

🆚 Secrets Manager vs Hard-Coded Secrets

Here's the difference I now keep in mind:
ApproachSecurityRotationCentral 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
│
▼
KMS
The 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/API
Lambda 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
│
▼
Database
The 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 Credentials
This 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-secret
I shouldn't automatically give it permission to retrieve:
1
every-secret-in-the-account
Instead, I want the permission to be as narrow as practical.
Conceptually:
1
2
3
4
5
6
7
Lambda
│
└── IAM Role
│
└── Can retrieve
│
└── Specific Secret
This 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 controls
This 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/API
And IAM controls access:
1
2
3
4
5
6
7
8
9
IAM
│
┌────────────┴────────────┐
▼ ▼
Lambda EC2
│ │
└──────────┬──────────────┘
▼
Secrets Manager
Now 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 Credentials
Instead 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. 🔐☁️
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