salesforce-development
Expert patterns for Salesforce platform development including Lightning Web Components (LWC), Apex triggers and classes, REST/Bulk APIs, Connected Apps, and Salesforce DX with scratch orgs and 2nd ...
aws-secrets-rotation
Automate AWS secrets rotation for RDS, API keys, and credentials
Full skill instructions
Automate rotation of secrets, credentials, and API keys using AWS Secrets Manager and Lambda.
Use this skill when you need to implement automated secrets rotation, manage credentials securely, or comply with security policies requiring regular key rotation.
AWS Services
Third-Party Services
# Create RDS secret
aws secretsmanager create-secret \
--name prod/db/mysql \
--description "Production MySQL credentials" \
--secret-string '{
"username": "admin",
"password": "CHANGE_ME",
"engine": "mysql",
"host": "mydb.cluster-abc.us-east-1.rds.amazonaws.com",
"port": 3306,
"dbname": "myapp"
}'
# Create API key secret
aws secretsmanager create-secret \
--name prod/api/stripe \
--secret-string '{
"api_key": "sk_live_xxxxx",
"webhook_secret": "whsec_xxxxx"
}'
# Create secret from file
aws secretsmanager create-secret \
--name prod/ssh/private-key \
--secret-binary fileb://~/.ssh/id_rsa
# Get secret value
aws secretsmanager get-secret-value \
--secret-id prod/db/mysql \
--query 'SecretString' --output text
# Get specific field
aws secretsmanager get-secret-value \
--secret-id prod/db/mysql \
--query 'SecretString' --output text | \
jq -r '.password'
# Get binary secret
aws secretsmanager get-secret-value \
--secret-id prod/ssh/private-key \
--query 'SecretBinary' --output text | \
base64 -d > private-key.pem
# Enable automatic rotation (30 days)
aws secretsmanager rotate-secret \
--secret-id prod/db/mysql \
--rotation-lambda-arn arn:aws:lambda:us-east-1:123456789012:function:SecretsManagerRDSMySQLRotation \
--rotation-rules AutomaticallyAfterDays=30
# Rotate immediately
aws secretsmanager rotate-secret \
--secret-id prod/db/mysql
# Check rotation status
aws secretsmanager describe-secret \
--secret-id prod/db/mysql \
--query 'RotationEnabled'
# lambda_rotation.py
import boto3
import json
import os
secrets_client = boto3.client('secretsmanager')
rds_client = boto3.client('rds')
def lambda_handler(event, context):
"""Rotate RDS MySQL password"""
secret_arn = event['SecretId']
token = event['ClientRequestToken']
step = event['Step']
# Get current secret
current = secrets_client.get_secret_value(SecretId=secret_arn)
secret = json.loads(current['SecretString'])
if step == "createSecret":
# Generate new password
new_password = generate_password()
secret['password'] = new_password
# Store as pending
secrets_client.put_secret_value(
SecretId=secret_arn,
ClientRequestToken=token,
SecretString=json.dumps(secret),
VersionStages=['AWSPENDING']
)
elif step == "setSecret":
# Update RDS password
rds_client.modify_db_instance(
DBInstanceIdentifier=secret['dbInstanceIdentifier'],
MasterUserPassword=secret['password'],
ApplyImmediately=True
)
elif step == "testSecret":
# Test new credentials
import pymysql
conn = pymysql.connect(
host=secret['host'],
user=secret['username'],
password=secret['password'],
database=secret['dbname']
)
conn.close()
elif step == "finishSecret":
# Mark as current
secrets_client.update_secret_version_stage(
SecretId=secret_arn,
VersionStage='AWSCURRENT',
MoveToVersionId=token,
RemoveFromVersionId=current['VersionId']
)
return {'statusCode': 200}
def generate_password(length=32):
import secrets
import string
alphabet = string.ascii_letters + string.digits + "!@#$%^&*()"
return ''.join(secrets.choice(alphabet) for _ in range(length))
# api_key_rotation.py
import boto3
import requests
import json
secrets_client = boto3.client('secretsmanager')
def rotate_stripe_key(secret_arn, token, step):
"""Rotate Stripe API key"""
current = secrets_client.get_secret_value(SecretId=secret_arn)
secret = json.loads(current['SecretString'])
if step == "createSecret":
# Create new Stripe key via API
response = requests.post(
'https://api.stripe.com/v1/api_keys',
auth=(secret['api_key'], ''),
data={'name': f'rotated-{token[:8]}'}
)
new_key = response.json()['secret']
secret['api_key'] = new_key
secrets_client.put_secret_value(
SecretId=secret_arn,
ClientRequestToken=token,
SecretString=json.dumps(secret),
VersionStages=['AWSPENDING']
)
elif step == "testSecret":
# Test new key
response = requests.get(
'https://api.stripe.com/v1/balance',
auth=(secret['api_key'], '')
)
if response.status_code != 200:
raise Exception("New key failed validation")
elif step == "finishSecret":
# Revoke old key
old_key = json.loads(current['SecretString'])['api_key']
requests.delete(
f'https://api.stripe.com/v1/api_keys/{old_key}',
auth=(secret['api_key'], '')
)
# Promote to current
secrets_client.update_secret_version_stage(
SecretId=secret_arn,
VersionStage='AWSCURRENT',
MoveToVersionId=token
)
# Create alarm for rotation failures
aws cloudwatch put-metric-alarm \
--alarm-name secrets-rotation-failures \
--alarm-description "Alert on secrets rotation failures" \
--metric-name RotationFailed \
--namespace AWS/SecretsManager \
--statistic Sum \
--period 300 \
--evaluation-periods 1 \
--threshold 1 \
--comparison-operator GreaterThanThreshold \
--alarm-actions arn:aws:sns:us-east-1:123456789012:alerts
#!/bin/bash
# audit-rotations.sh
echo "Secrets Rotation Audit"
echo "====================="
aws secretsmanager list-secrets --query 'SecretList[*].[Name,RotationEnabled,LastRotatedDate]' \
--output text | \
while read name enabled last_rotated; do
echo ""
echo "Secret: $name"
echo " Rotation Enabled: $enabled"
echo " Last Rotated: $last_rotated"
if [ "$enabled" = "True" ]; then
# Check rotation schedule
rules=$(aws secretsmanager describe-secret --secret-id "$name" \
--query 'RotationRules.AutomaticallyAfterDays' --output text)
echo " Rotation Schedule: Every $rules days"
# Calculate days since last rotation
if [ "$last_rotated" != "None" ]; then
days_ago=$(( ($(date +%s) - $(date -d "$last_rotated" +%s)) / 86400 ))
echo " Days Since Rotation: $days_ago"
if [ $days_ago -gt $rules ]; then
echo " ⚠️ OVERDUE for rotation!"
fi
fi
fi
done
import boto3
import json
def get_secret(secret_name):
"""Retrieve secret from Secrets Manager"""
client = boto3.client('secretsmanager')
try:
response = client.get_secret_value(SecretId=secret_name)
return json.loads(response['SecretString'])
except Exception as e:
print(f"Error retrieving secret: {e}")
raise
# Usage
db_creds = get_secret('prod/db/mysql')
connection = pymysql.connect(
host=db_creds['host'],
user=db_creds['username'],
password=db_creds['password'],
database=db_creds['dbname']
)
const AWS = require('aws-sdk');
const secretsManager = new AWS.SecretsManager();
async function getSecret(secretName) {
try {
const data = await secretsManager.getSecretValue({
SecretId: secretName
}).promise();
return JSON.parse(data.SecretString);
} catch (err) {
console.error('Error retrieving secret:', err);
throw err;
}
}
// Usage
const dbCreds = await getSecret('prod/db/mysql');
const connection = mysql.createConnection({
host: dbCreds.host,
user: dbCreds.username,
password: dbCreds.password,
database: dbCreds.dbname
});
Planning
Implementation
Operations
# Immediate rotation (compromise detected)
aws secretsmanager rotate-secret \
--secret-id prod/db/mysql \
--rotate-immediately
# Force rotation even if recently rotated
aws secretsmanager rotate-secret \
--secret-id prod/api/stripe \
--rotation-lambda-arn arn:aws:lambda:us-east-1:123456789012:function:RotateStripeKey \
--rotate-immediately
# Verify rotation completed
aws secretsmanager describe-secret \
--secret-id prod/db/mysql \
--query 'LastRotatedDate'
#!/usr/bin/env python3
# compliance-report.py
import boto3
from datetime import datetime, timedelta
client = boto3.client('secretsmanager')
def generate_compliance_report():
secrets = client.list_secrets()['SecretList']
compliant = []
non_compliant = []
for secret in secrets:
name = secret['Name']
rotation_enabled = secret.get('RotationEnabled', False)
last_rotated = secret.get('LastRotatedDate')
if not rotation_enabled:
non_compliant.append({
'name': name,
'issue': 'Rotation not enabled'
})
continue
if last_rotated:
days_ago = (datetime.now(last_rotated.tzinfo) - last_rotated).days
if days_ago > 90:
non_compliant.append({
'name': name,
'issue': f'Not rotated in {days_ago} days'
})
else:
compliant.append(name)
else:
non_compliant.append({
'name': name,
'issue': 'Never rotated'
})
print(f"Compliant Secrets: {len(compliant)}")
print(f"Non-Compliant Secrets: {len(non_compliant)}")
print("\nNon-Compliant Details:")
for item in non_compliant:
print(f" - {item['name']}: {item['issue']}")
if __name__ == "__main__":
generate_compliance_report()
kiro-cli chat "Use aws-secrets-rotation to set up RDS credential rotation"
kiro-cli chat "Create a rotation audit report with aws-secrets-rotation"
Expert patterns for Salesforce platform development including Lightning Web Components (LWC), Apex triggers and classes, REST/Bulk APIs, Connected Apps, and Salesforce DX with scratch orgs and 2nd ...
Instrument applications with Azure Monitor and OpenTelemetry for JavaScript (@azure/monitor-opentelemetry). Use when adding distributed tracing, metrics, and logs to Node.js applications with Appli...
Create and optimize popups, modals, overlays, slide-ins, and banners to increase conversions without harming user experience or brand trust.
Configure mutual TLS (mTLS) for zero-trust service-to-service communication. Use when implementing zero-trust networking, certificate management, or securing internal service communication.
Build Azure Cosmos DB NoSQL services with Python/FastAPI following production-grade patterns. Use when implementing database client setup with dual auth (DefaultAzureCredential + emulator), service...
Terraform infrastructure as code workflow for provisioning cloud resources, creating reusable modules, and managing infrastructure at scale.
Automate OneDrive file management, search, uploads, downloads, sharing, permissions, and folder operations via Rube MCP (Composio). Always search tools first for current schemas.
Implement memory-safe programming with RAII, ownership, smart pointers, and resource management across Rust, C++, and C. Use when writing safe systems code, managing resources, or preventing memory...
Handle errors as values using fp-ts Either and TaskEither for cleaner, more predictable TypeScript code. Use when implementing error handling patterns with fp-ts.
You are a code migration expert specializing in transitioning codebases between frameworks, languages, versions, and platforms. Generate comprehensive migration plans, automated migration scripts, and
Real-time, bidirectional voice conversations with AI assistants using WebSocket technology.
A hybrid memory system that provides persistent, searchable knowledge management for AI agents (Architecture, Patterns, Decisions).
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience