Rotating Secrets in AWS Secrets Manager Using AWS Lambda
When building applications in the cloud, one of the most common security mistakes is hardcoding credentials or leaving them unchanged for long periods. It might work during development, but in production, static credentials become a serious risk.
Imagine this scenario:
Your application connects to a database using a username and password stored in environment variables. Months pass,
teams change, logs get shared, and suddenly someone realizes the credentials have never been rotated.
This is exactly the type of problem AWS Secrets Manager is designed to solve. It not only stores secrets securely, but also allows you to automatically rotate them using AWS Lambda.
In this guide, we’ll walk through a beginner-friendly, practical approach to rotating database credentials using AWS Secrets Manager and AWS Lambda with Node.js.
![]() |
| Automated Secret Rotation with AWS Lambda |
Importance of Secret Rotation
Before jumping into implementation, let’s understand why secret rotation is important.
Risks of Static Credentials
-
Credentials may be exposed in logs or code.
-
Old credentials may still work after employees leave.
-
Compromised credentials may remain valid indefinitely.
Benefits of Automatic Rotation
-
Credentials change periodically.
-
Reduced blast radius in case of compromise.
-
No manual intervention required.
-
Fully managed and auditable.
AWS Secrets Manager automates this process by integrating with Lambda functions.
AWS Secret Rotation Mechanism
When you enable rotation in AWS Secrets Manager:
-
AWS triggers a Lambda function.
-
The Lambda performs the rotation logic.
-
Secrets Manager manages secret versions.
AWS follows a four-step rotation process:
- createSecret: Generate new credentials.
- setSecret: Apply new credentials to the database.
- testSecret: Verify the new credentials work.
- finishSecret: Mark the new version as active.
Your Lambda function must handle each of these steps.
Architecture Overview
Simple flow:
-
Application reads DB credentials from Secrets Manager.
-
Secrets Manager triggers Lambda on rotation schedule.
-
Lambda:
-
Generates a new password.
-
Updates the database.
-
Updates the secret value.
Step 1: Create a Secret in AWS Secrets Manager
-
Goto AWS Secrets Manager.
-
Click store a new secret.
-
Choose credential for RDS database.
-
Enter:
-
Username
-
Password
- Choose your Database.
- Name the Secret and Finish the setup.
Step 2: Create the Rotation Lambda Function
Create a Lambda function with:
- Runtime: Node.js 18+
-
Role with Permissions to Secrets Manager and Database.
Step 3: Lambda Rotation Function (Node.js Example)
Below is a simplified rotation Lambda example for a MySQL database.
const AWS = require('aws-sdk');
const crypto = require('crypto');
const mysql = require('mysql2/promise');
const secretsManager = new AWS.SecretsManager();
exports.handler = async (event) => {
const step = event.Step;
const secretId = event.SecretId;
const token = event.ClientRequestToken;
console.log(`Rotation step: ${step}`);
switch (step) {
case "createSecret":
await createSecret(secretId, token);
break;
case "setSecret":
await setSecret(secretId, token);
break;
case "testSecret":
await testSecret(secretId, token);
break;
case "finishSecret":
await finishSecret(secretId, token);
break;
default:
throw new Error("Invalid step");
}
};
Step Logic Implementations
1. Create Secret
Generate a new password.
async function createSecret(secretId, token) {
const newPassword = crypto.randomBytes(16).toString('hex');
const secret = await secretsManager.getSecretValue({
SecretId: secretId,
VersionStage: "AWSCURRENT"
}).promise();
const currentSecret = JSON.parse(secret.SecretString);
const newSecret = {
...currentSecret,
password: newPassword
};
await secretsManager.putSecretValue({
SecretId: secretId,
ClientRequestToken: token,
SecretString: JSON.stringify(newSecret),
VersionStages: ["AWSPENDING"]
}).promise();
console.log("New secret version created.");
}
2. Set Secret
Update the database with the new password.
async function setSecret(secretId, token) {
const pendingSecret = await secretsManager.getSecretValue({
SecretId: secretId,
VersionStage: "AWSPENDING"
}).promise();
const secret = JSON.parse(pendingSecret.SecretString);
const connection = await mysql.createConnection({
host: secret.host,
user: secret.username,
password: secret.password,
database: secret.dbname
});
await connection.execute(
`ALTER USER '${secret.username}'@'%' IDENTIFIED BY '${secret.password}'`
);
await connection.end();
console.log("Database password updated.");
}
3. Test Secret
Verify the new credentials work.
async function testSecret(secretId, token) {
const pendingSecret = await secretsManager.getSecretValue({
SecretId: secretId,
VersionStage: "AWSPENDING"
}).promise();
const secret = JSON.parse(pendingSecret.SecretString);
const connection = await mysql.createConnection({
host: secret.host,
user: secret.username,
password: secret.password,
database: secret.dbname
});
await connection.execute("SELECT 1");
await connection.end();
console.log("New credentials verified.");
}
4. Finish Secret
Promote the new version.
async function finishSecret(secretId, token) {
await secretsManager.updateSecretVersionStage({
SecretId: secretId,
VersionStage: "AWSCURRENT",
MoveToVersionId: token
}).promise();
console.log("Secret rotation completed.");
}
Step 4: Enable Rotation in Secrets Manager
-
Open your secret.
-
Click Enable rotation.
-
Choose:
-
Rotation Lambda: your function.
-
Rotation schedule: e.g., every 30 days.
-
AWS will now automatically rotate the secret.
Step 5: Test the Rotation
Trigger rotation manually:
-
Go to Secrets Manager.
-
Select your secret.
-
Click Rotate secret immediately.
Then:
-
Check Lambda logs in CloudWatch.
-
Confirm database password updated.
-
Confirm new secret version marked as
AWSCURRENT.
Best Practices for Secret Rotation
1. Use Least Privilege IAM Roles
Your Lambda should only have access to:
-
The specific secret
-
The specific database
2. Use Secure Password Generation
Always use crypto.randomBytes() instead of hardcoded values.
3. Monitor Rotation Failures
Set CloudWatch alarms for:
-
Lambda errors
-
Rotation failures
4. Test Rotation in Non-Production First
Always validate rotation in a staging environment.
Common Beginner Mistakes
-
Forgetting to test the new credentials.
-
Not updating database permissions properly.
-
Using overly broad IAM roles.
-
Ignoring rotation logs.
-
Not verifying the AWSCURRENT stage.
Conclusion
Secret rotation is one of the simplest and most effective ways to improve your application’s security posture. With AWS Secrets Manager and Lambda, you can automate the entire process without manual intervention.
Do not treat secrets as static values. Treat them as short-lived credentials that should be rotated automatically.

No comments:
Post a Comment