14.4 Automated Secrets Management & Secret Rotation with Secrets Manager
Key Takeaways
- AWS Secrets Manager provides encrypted secret storage using AWS KMS, supporting automated rotation via AWS Lambda and fine-grained version staging labels (AWSCURRENT, AWSPREVIOUS, AWSPENDING).
- The 4-step rotation protocol (createSecret, setSecret, testSecret, finishSecret) guarantees that new credentials are fully written to the target database and verified before being promoted to AWSCURRENT.
- When rotating database credentials in private VPC subnets, the rotation Lambda function must be attached to the private VPC with security group access to the database, while reaching Secrets Manager and KMS via VPC Interface Endpoints (PrivateLink).
- Single-user rotation incurs a potential race condition and transient connection failures during password update, whereas alternating dual-user rotation achieves zero-downtime database rotation by alternating between two active application accounts.
- High-throughput microservices must utilize AWS Secrets Manager client-side caching libraries with configurable TTLs to eliminate latency, prevent API rate throttling (ThrottlingException), and eliminate unnecessary API costs.
AWS Secrets Manager Architecture & Core Capabilities
Hardcoded database credentials, API tokens, and private encryption keys inside source code repositories or configuration files represent one of the most severe security vulnerabilities in modern DevOps pipelines. AWS Secrets Manager eliminates this risk by providing centralized, encrypted secret storage with native automated lifecycle rotation.
Secret Storage and Encryption Mechanics
- Payload Format: Secrets Manager stores secrets as JSON key-value pairs (ideal for database credentials:
username,password,host,port,dbname) or arbitrary binary/plaintext strings. - AWS KMS Envelope Encryption: All secrets are encrypted at rest using AWS Key Management Service (KMS). Organizations can utilize the default AWS-managed key (
aws/secretsmanager) or a Customer Managed Key (CMK). A CMK is mandatory when secrets must be shared across AWS accounts or when strict regulatory compliance mandates customer-controlled key rotation and auditing. - Resource-Based Policies: Secrets Manager secrets support resource-based policies. This allows a secret in a centralized Security or Shared Services account to be accessed directly by IAM execution roles in spoke application accounts without requiring cross-account role assumption.
Secret Versioning & Staging Labels
Secrets Manager versions are immutable. Each modification or rotation creates a new version containing a unique VersionId (UUID). Versions are tracked and manipulated using Staging Labels:
| Staging Label | Lifecycle State & Functional Role |
|---|---|
AWSCURRENT | The active version of the secret. Active applications query this version by default when calling GetSecretValue without specifying a VersionId or VersionStage. Exactly one version can hold AWSCURRENT at any time. |
AWSPREVIOUS | The version that immediately preceded the current version. Maintained for instantaneous rollback if a recently rotated credential causes unforeseen application faults. Exactly one version holds AWSPREVIOUS. |
AWSPENDING | The newly generated staging version undergoing active rotation and verification. Staged during the rotation workflow and promoted to AWSCURRENT only after rigorous connectivity testing succeeds. |
| Custom Labels | Arbitrary labels attached by operators or automated CI/CD deployment scripts (e.g., staging-v2, green-deployment) to support blue/green application deployment models. |
The 4-Step Rotation Protocol
When automated rotation is enabled (e.g., every 30 days) or manually triggered via the RotateSecret API, Secrets Manager initiates an execution workflow that invokes an AWS Lambda rotation function four consecutive times. Each invocation passes a specific Step parameter in the event payload:
Secrets Manager Rotation Engine
│
├─ 1. Step: "createSecret" ──> Lambda creates AWSPENDING version with new random password
│
├─ 2. Step: "setSecret" ────> Lambda connects to DB (as AWSCURRENT or Master) and updates DB password
│
├─ 3. Step: "testSecret" ───> Lambda tests DB connection using AWSPENDING password
│
└─ 4. Step: "finishSecret" ─> Lambda moves AWSCURRENT label to AWSPENDING; marks old version AWSPREVIOUS
The Four Steps in Detail
createSecret: The Lambda function queries Secrets Manager to determine if a version with theAWSPENDINGstaging label already exists. If not, it generates a cryptographically secure random password (e.g., usingsecrets.token_urlsafeorGetRandomPassword) and writes the new credentials to Secrets Manager under a newVersionIdlabeledAWSPENDING. IfAWSPENDINGalready exists, it leaves it intact to ensure idempotency across automated retries.setSecret: The Lambda function retrieves the current credentials (fromAWSCURRENTor master credentials) and establishes an administrative connection to the target database engine (e.g., Amazon RDS MySQL, PostgreSQL, or Aurora). It executes anALTER USERorSET PASSWORDstatement to update the database user's password in the database engine to match the password stored in theAWSPENDINGsecret version.testSecret: The Lambda function attempts to establish a brand-new database connection using theAWSPENDINGcredentials. It executes a lightweight validation query (such asSELECT 1;). If authentication fails, the function raises an exception, the rotation process halts, andAWSCURRENTremains completely unchanged.finishSecret: OncetestSecretsucceeds, the Lambda function calls the Secrets ManagerUpdateSecretVersionStageAPI. It moves theAWSCURRENTlabel from the old version to theAWSPENDINGversion, automatically appliesAWSPREVIOUSto the older version, and strips theAWSPENDINGlabel. Applications queryingGetSecretValuenow receive the newly validated credentials.
[!IMPORTANT] Idempotency Requirement: Secrets Manager can retry any rotation step if a transient network failure occurs. The Lambda rotation function must be written to be strictly idempotent. For instance, in
setSecret, if the database password was already updated in an earlier attempt that timed out during response delivery, the Lambda function must verify connectivity withAWSPENDINGbefore failing.
Private VPC Networking for Secrets Manager Rotation
In enterprise production environments, databases (Amazon RDS, Amazon Aurora) are deployed inside isolated private VPC subnets without public internet access or public IP addresses. This creates a critical networking requirement for the rotation Lambda function.
┌────────────────────────────────────────────────────────────────────────┐
│ Amazon VPC (10.0.0.0/16) │
│ │
│ ┌────────────────────────────────┐ ┌──────────────────────────┐ │
│ │ Private Application Subnet │ │ Private Database Subnet │ │
│ │ │ │ │ │
│ │ [ Lambda Rotation Function ] │───>│ [ Amazon RDS Database ] │ │
│ │ Attached to VPC Subnets │TCP │ Port 3306 / 5432 │ │
│ │ Security Group: Lambda-SG │ │ Security Group: DB-SG │ │
│ └───────────────┬────────────────┘ └──────────────────────────┘ │
│ │ │
│ │ HTTPS (Port 443) via AWS PrivateLink │
│ ▼ │
│ ┌────────────────────────────────┐ ┌──────────────────────────┐ │
│ │ VPC Interface Endpoint: │ │ VPC Interface Endpoint: │ │
│ │ com.amazonaws.<reg>.secretsmanager │ │ com.amazonaws.<reg>.kms │ │
│ └────────────────────────────────┘ └──────────────────────────┘ │
└────────────────────────────────────────────────────────────────────────┘
Mandatory Networking Components
- VPC Subnet Attachment: The Lambda rotation function must be configured with VPC attachment, placing its Elastic Network Interfaces (ENIs) inside the private subnets where the database is reachable.
- Security Group Rules:
- Database Security Group: Must have an inbound rule allowing TCP traffic on the database port (e.g., 3306 for MySQL, 5432 for PostgreSQL) originating from the Lambda function's security group.
- Lambda Security Group: Outbound rule allowing traffic to the database security group on the database port, and outbound rule allowing HTTPS (port 443) to the VPC Interface Endpoints.
- AWS PrivateLink (VPC Interface Endpoints):
Because the Lambda function is inside a private VPC without internet access (no NAT Gateway or Internet Gateway), it cannot reach the public Secrets Manager or AWS KMS API endpoints. You must provision VPC Interface Endpoints for:
com.amazonaws.<region>.secretsmanagercom.amazonaws.<region>.kms(if using customer-managed KMS keys)- Both endpoints must have Private DNS enabled and attach a security group allowing inbound HTTPS (port 443) from the Lambda rotation function.
Rotation Strategies: Single-User vs. Alternating Dual-User
| Architectural Attribute | Single-User Rotation Strategy | Alternating Dual-User Rotation Strategy |
|---|---|---|
| Account Management | Rotates credentials for a single database user | Manages two distinct database users (UserA and UserB) plus a Master secret |
| Downtime & Race Conditions | Potential Downtime: In setSecret, the password changes in the DB immediately. Any application connection pool using old credentials will fail until the app updates its cache. | Zero Downtime: While UserA is active in AWSCURRENT, UserB is rotated and updated in the DB. Existing application connections continue using UserA without interruption. |
| Target Database Users | Non-critical internal tools, background ETL scripts | Production databases, high-availability microservices, 24/7 web applications |
| Prerequisites | User has permissions to alter its own password | Requires a separate Master Secret containing administrative credentials to alter user passwords |
[ Dual-User Zero-Downtime Rotation Cycle ]
Phase 1 (Normal Operations):
- Database Users: User_A (Active), User_B (Standby)
- Secrets Manager: AWSCURRENT points to User_A
- Applications connect using User_A
Phase 2 (Rotation Triggered):
- Master Secret used to connect to database
- Lambda alters User_B's password in the database to AWSPENDING password
- Lambda tests connection using User_B with AWSPENDING password
- Applications continue processing transactions using User_A uninterrupted!
Phase 3 (Promotion):
- finishSecret promotes User_B to AWSCURRENT; User_A becomes AWSPREVIOUS
- Applications refresh credentials and transition seamlessly to User_B
Client-Side Caching & Scalability
In high-throughput microservices architectures (e.g., an Amazon EKS cluster processing 20,000 requests per second), applications must never call GetSecretValue on every incoming transaction. Secrets Manager API calls are rate-limited per region and incur costs ($0.05 per 10,000 API calls). Querying Secrets Manager per request triggers ThrottlingException: Rate exceeded and generates massive AWS bills.
AWS Secrets Manager Client-Side Caching Libraries
AWS provides native open-source caching libraries (for Java, Python, Go, Node.js, and .NET):
- In-Memory Caching: Credentials are cached in application process memory with a configurable Time-to-Live (TTL, e.g., default of 300 seconds / 5 minutes to 1 hour).
- Asynchronous Background Refresh: Caching libraries refresh secrets in the background before the TTL expires, ensuring zero added latency for user requests.
- Authentication Failure Hook: If the application experiences an authentication failure (
AccessDeniedorSQLException), the caching library automatically invalidates the cached secret immediately and performs a synchronous freshGetSecretValuecall to fetch the newly rotatedAWSCURRENTcredentials.
An enterprise financial transactions microservice connects to an Amazon Aurora PostgreSQL database cluster. The security compliance policy requires that database credentials must be automatically rotated every 30 days. The application cannot tolerate any dropped database transactions or connection errors during the rotation window. During a trial run using Secrets Manager standard single-user rotation, several active transactions failed during the rotation period due to authentication errors. What architectural pattern should the DevOps engineer implement to eliminate application downtime during rotation?
A DevOps engineer configures automated 30-day rotation for an Amazon RDS MySQL secret using AWS Secrets Manager. The RDS instance resides in private VPC subnets with no internet gateway or NAT gateway attached. The engineer configures the Secrets Manager rotation Lambda function to run inside the same private VPC subnets and security group as the database. However, when the automated rotation triggers, the Lambda function times out after 15 minutes in the createSecret step. CloudWatch logs show that the Lambda function fails to connect to the Secrets Manager service endpoint. What is the root cause and the required remediation?
An e-commerce platform running on Amazon EKS consists of 150 microservice pods handling 10,000 incoming requests per second. Each microservice pod invokes the AWS SDK GetSecretValue API call to AWS Secrets Manager to retrieve database credentials on every incoming HTTP request. Shortly after launching a major marketing campaign, customer checkouts begin failing with HTTP 500 errors, and CloudWatch metrics reveal high volumes of ThrottlingException: Rate exceeded errors from Secrets Manager along with an extreme surge in AWS billing charges. How should the DevOps engineer remediate this scalability and cost bottleneck?