CtrlK
BlogDocsLog inGet started
Tessl Logo
SkillPublic

aws-secrets-rotation

Automate AWS secrets rotation for RDS, API keys, and credentials

Quality

69%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide
SecuritybySnyk

Passed

No findings from the security scan

Fix and improve this skill with Tessl

tessl review fix ./skills/antigravity-aws-secrets-rotation/SKILL.md
SKILL.md
Quality
Evals
Security

AWS Secrets Rotation

Automate rotation of secrets, credentials, and API keys using AWS Secrets Manager and Lambda.

Review scope and execution boundaries

Select the exact account/role, partition, regions and control/framework version before collecting evidence; verify identity with aws sts get-caller-identity. Read-only assessment is the default. Commands that create MFA devices, change policies/keys, enable services, rotate secrets or create alarms require an approved change scope and rollback plan. Keep evidence and secret material out of shared logs.

These are partial examples, not certification or complete benchmark implementations. Control numbers are illustrative historical mappings, not a pinned current benchmark. Record PASS/FAIL/UNKNOWN/NOT-APPLICABLE per control with evidence and coverage. AccessDenied, API errors, missing permissions, absent pages and unimplemented checks are UNKNOWN, never PASS. Use paginators for SDK listings and cover all selected regions/accounts; never infer completeness from no findings. Shell snippets require Bash/GNU date, AWS CLI, jq and error checking (set -euo pipefail in complete scripts). Generate the IAM credential report first, wait for COMPLETE and decode its base64 Content; parse CSV by header in production. Credential reports are sensitive.

When to Use

Use this skill when you need to implement automated secrets rotation, manage credentials securely, or comply with security policies requiring regular key rotation.

Supported Secret Types

AWS Services

  • RDS database credentials
  • DocumentDB credentials
  • Redshift credentials
  • ElastiCache credentials

Third-Party Services

  • API keys
  • OAuth tokens
  • SSH keys
  • Custom credentials

Secrets Manager Setup

Create a Secret

Placeholders below are not deployable credentials. Use private input files (--secret-string file://...) rather than inline real secret values visible in shell history/process arguments. Binary output files need umask 077 and exclusive creation; never overwrite a real private key.

# 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

Retrieve Secrets

# 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 --decode > "$PRIVATE_OUTPUT_FILE"  # fresh private path, umask 077

Automatic Rotation Setup

Enable RDS Rotation

# 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 configuration only; completion requires expected VersionId at AWSCURRENT
# and successful target authentication/consumer refresh.
aws secretsmanager describe-secret \
  --secret-id prod/db/mysql \
  --query 'RotationEnabled'

Lambda rotation implementation

Use the AWS-maintained rotation template appropriate to the database/service and verify its permissions and network prerequisites. A function must validate SecretId, rotation enabled state, ClientRequestToken membership and AWSPENDING stage before mutation; already-current tokens should return idempotently.

  1. createSecret: reuse an existing pending version for this token or generate/store it once.
  2. setSecret: retrieve that exact pending VersionId and AWSPENDING stage; verify current/pending refer to the same authorized host/account/user before changing the target. Never update the database with AWSCURRENT by mistake.
  3. testSecret: connect using the pending credentials, bounded timeouts, TLS verification and minimum permissions; close connections on all paths.
  4. finishSecret: promote the tested pending version; remove AWSCURRENT from the previous version only as documented. Monitor consumers and retain a recovery path.

Do not substitute an asynchronous master-password modification for a working database-user rotation implementation. Application refresh, overlapping credentials and retry/idempotency behavior need integration tests.

Stripe and other provider API keys

Stripe documents creation, expiration and rotation through its Dashboard. This skill does not provide a verified key-management API. Do not call invented /v1/api_keys creation/revocation endpoints or put secret key material in URL paths. Follow the provider's documented workflow, stage the replacement privately in Secrets Manager, update/test consumers, and revoke the old key after confirmed rollout. Webhook signing secrets are a separate credential.

Rotation Monitoring

CloudWatch Alarms

The following is a custom metric contract, not a guaranteed native Secrets Manager metric. Publish RotationFailed in your own namespace from monitored failure events; verify a test failure reaches the alarm and SNS destination. An alarm on a nonexistent series does not detect failures.

# 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 MyApp/SecretRotation \
  --statistic Sum \
  --period 300 \
  --evaluation-periods 1 \
  --threshold 1 \
  --comparison-operator GreaterThanOrEqualToThreshold \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:alerts

Rotation Audit Script

#!/bin/bash
# audit-rotations.sh

echo "Secrets Rotation Audit"
echo "====================="

aws secretsmanager list-secrets --query 'SecretList[*].[Name,RotationEnabled,LastRotatedDate]' \
  --output text | tr '\t' '\n' | \
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

Application Integration

Python SDK

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']
)

Node.js SDK

This is legacy AWS SDK v2 syntax. For a new integration use the installed AWS SDK v3 SecretsManagerClient/GetSecretValueCommand API and its current credential chain. Do not log complete SDK errors or secret responses.

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
});

Rotation Best Practices

Planning

  • Identify all secrets requiring rotation
  • Define rotation schedules (30, 60, 90 days)
  • Test rotation in non-production first
  • Document rotation procedures
  • Plan for emergency rotation

Implementation

  • Use AWS managed rotation when possible
  • Implement proper error handling
  • Add CloudWatch monitoring
  • Test application compatibility
  • Implement gradual rollout

Operations

  • Monitor rotation success/failure
  • Set up alerts for failures
  • Regular rotation audits
  • Document troubleshooting steps
  • Maintain rotation runbooks

Emergency Rotation

# 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

# LastRotatedDate alone does not prove this requested rotation completed.
aws secretsmanager describe-secret \
  --secret-id prod/db/mysql \
  --query 'LastRotatedDate'

Compliance Tracking

#!/usr/bin/env python3
# compliance-report.py

import boto3
from datetime import datetime, timedelta

client = boto3.client('secretsmanager')

def generate_compliance_report():
    secrets = [s for page in client.get_paginator('list_secrets').paginate() for s in page['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()

Example Prompts

  • "Set up automatic rotation for my RDS credentials"
  • "Create a Lambda function to rotate API keys"
  • "Audit all secrets for rotation compliance"
  • "Implement emergency rotation for compromised credentials"
  • "Generate a secrets rotation report"

Kiro CLI Integration

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"

Additional Resources

  • AWS Secrets Manager Rotation
  • Rotation Lambda Templates
  • Best Practices for Secrets

Limitations

  • Use this skill only when the task clearly matches the scope described above.
  • Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
  • Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.
Repository

boisenoise/skills-collections

Path

skills/antigravity-aws-secrets-rotation/SKILL.md

Last updated
First committed

Also appears in

popey/claude-code-skills
Stale

last in sync Apr 14, 2026

popey/claude-code-skills
Stale

last in sync Apr 14, 2026

popey/claude-code-skills
Stale

last in sync Apr 14, 2026

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.