AWS Secrets Manager and Parameter Store
Applications need configuration values and secrets to function — database passwords, API keys, connection strings, and environment-specific settings. Hardcoding these values in application code or storing them in plain text configuration files creates serious security risks. AWS provides two services to solve this problem: AWS Secrets Manager and AWS Systems Manager Parameter Store.
The Problem: Hardcoded Secrets
A common mistake in application development is storing sensitive values directly in code:
# BAD PRACTICE — never do this DB_PASSWORD = "MyP@ssword123!" API_KEY = "sk-abc123xyz987"
If this code is pushed to a public GitHub repository (accidentally or intentionally), the credentials are exposed globally. Even in private repositories, anyone with code access can see the secrets. Rotating the password requires redeploying code.
The correct approach: store secrets outside the code, retrieve them at runtime using Secrets Manager or Parameter Store.
AWS Secrets Manager
AWS Secrets Manager stores, manages, and rotates sensitive credentials — database passwords, API keys, OAuth tokens — securely. Applications retrieve secrets at runtime using the AWS SDK or CLI instead of having them hardcoded.
Key Features
Secret Storage
A secret is stored as a key-value JSON object, encrypted using AWS KMS. Example secret stored for a database:
Secret Name: prod/myapp/database
Secret Value:
{
"username": "admin",
"password": "T$9xKp!mN2qR",
"host": "mydb.abc123.ap-south-1.rds.amazonaws.com",
"port": 5432,
"dbname": "appdb"
}
Automatic Secret Rotation
Secrets Manager can automatically rotate secrets on a defined schedule — daily, weekly, monthly — using a Lambda function. For RDS databases, AWS provides built-in rotation Lambda functions that update both the Secrets Manager value and the actual database password in sync.
Rotation Schedule: Every 30 days
|
[Secrets Manager triggers Lambda rotation function]
|
[Lambda generates new strong password]
|
[Lambda updates RDS database password]
|
[Lambda updates the secret value in Secrets Manager]
|
[Applications automatically use new password on next retrieval]
Applications do not need to be redeployed when passwords rotate. They retrieve the current secret value on each request (or cache it briefly).
Retrieving Secrets in Application Code
Python example — retrieve a database secret at runtime:
import boto3
import json
def get_db_credentials():
client = boto3.client('secretsmanager', region_name='ap-south-1')
response = client.get_secret_value(SecretId='prod/myapp/database')
secret = json.loads(response['SecretString'])
return secret['username'], secret['password'], secret['host']
The application never stores the password. It fetches it fresh from Secrets Manager each time (or caches it with a short TTL).
Secret Versioning
Secrets Manager maintains versions of each secret. During rotation, both the old (AWSPREVIOUS) and new (AWSCURRENT) versions exist simultaneously — allowing applications in the middle of a transaction to finish using the old password while new connections use the new one. This prevents rotation-related outages.
Secrets Manager Pricing
$0.40 per secret per month + $0.05 per 10,000 API calls. For a small application with 10 secrets, this costs about $4/month — far cheaper than a security incident from an exposed credential.
AWS Systems Manager Parameter Store
Parameter Store is part of AWS Systems Manager. It stores configuration data and secrets as named parameters. It is simpler and cheaper than Secrets Manager but lacks automatic rotation.
Parameter Types
| Type | Description | Encryption | Use Case |
|---|---|---|---|
| String | Plain text value | No | Application URLs, feature flags, environment names |
| StringList | Comma-separated list of plain text values | No | Allowed IP lists, environment-specific lists |
| SecureString | Encrypted value using KMS | Yes (KMS) | Passwords, API keys, connection strings |
Parameter Hierarchy
Parameters are organized in a hierarchical path structure, similar to folder paths. This allows grouping and retrieving parameters by environment or application:
/myapp/production/db-host = "prod-db.ap-south-1.rds.amazonaws.com" /myapp/production/db-password = "P@ssword!" (SecureString) /myapp/production/max-connections = "100" /myapp/staging/db-host = "stage-db.ap-south-1.rds.amazonaws.com" /myapp/staging/db-password = "StagePass!" (SecureString) /myapp/staging/max-connections = "20"
Retrieve all parameters for a given path at once:
aws ssm get-parameters-by-path \ --path /myapp/production \ --with-decryption
Standard vs Advanced Parameters
- Standard: Free, up to 10,000 parameters, max value size 4 KB.
- Advanced: $0.05 per parameter per month, up to 100,000 parameters, max value size 8 KB, supports parameter policies (TTL expiry, change notifications).
Secrets Manager vs Parameter Store
| Feature | Secrets Manager | Parameter Store |
|---|---|---|
| Automatic rotation | Yes — built-in Lambda rotation | No — must build custom rotation |
| Cross-account access | Yes | Limited |
| Cost | $0.40/secret/month | Free (Standard), $0.05/param/month (Advanced) |
| Max value size | 64 KB | 4 KB (Standard) / 8 KB (Advanced) |
| Native RDS integration | Yes — automated rotation for RDS | No |
| Best for | Database credentials, rotating secrets, API keys | App configuration, non-rotating values, feature flags |
Integration with EC2 and Lambda
Lambda
Lambda functions retrieve secrets at cold start and cache the value for the function's lifetime. The Lambda execution role must have secretsmanager:GetSecretValue or ssm:GetParameter permission.
EC2 via User Data
EC2 instances retrieve configuration from Parameter Store in the User Data startup script:
#!/bin/bash DB_HOST=$(aws ssm get-parameter \ --name /myapp/production/db-host \ --query Parameter.Value \ --output text) echo "DB_HOST=$DB_HOST" >> /etc/app.env
Real-World Example — Multi-Environment Application
A SaaS application deploys across three environments:
- Parameter Store stores non-sensitive config:
/saas/dev/api-url,/saas/prod/api-url, feature flags, and pagination limits. - Secrets Manager stores sensitive credentials: RDS passwords for each environment, Stripe API keys, and SendGrid API key.
- Secrets Manager automatically rotates the RDS production password every 7 days. The application never needs redeployment — it fetches the current secret on each database connection.
- All Lambda functions have IAM roles that allow access only to secrets within their specific environment path.
Summary
- Never hardcode secrets in application code. Secrets Manager and Parameter Store provide secure, centralized secret storage.
- Secrets Manager is designed for sensitive credentials with automatic rotation. Best for database passwords and API keys.
- Parameter Store stores both plain-text and encrypted configuration values. It is free (Standard) and suited for app configuration.
- Both services integrate with IAM for access control — applications only access the secrets they need.
- Automatic rotation in Secrets Manager eliminates the operational burden of manual credential updates.
