[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6EXCVVTNJ8QN5Z0QKW4NFWH":3,"skill-same:01M6EXCVVTNJ8QN5Z0QKW4NFWH":78},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":28,"publishedAt":43,"linkOnly":44,"markdownContent":45,"markdownBody":46,"frontMatter":47,"refName":49,"commitSha":50,"skillDirectory":51,"forksCount":52,"repositoryHtmlUrl":53,"repositoryHomepageUrl":54,"ownerHtmlUrl":55,"ownerBlogUrl":6,"ownerDescription":56,"updatedAt":57,"install":58,"resources":71},"01M6EXCVVTNJ8QN5Z0QKW4NFWH","aws-secrets-rotation",null,"Automate AWS secrets rotation for RDS, API keys, and credentials","ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",66,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fsickn33\u002Faws-secrets-rotation\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[29,30,31,32,33,34,35,36,37,38,39,40,41,42],"aws","secrets","aws secrets rotation","cli","safe","security","automation","credentials","api","automate","community","kiro","kiro-cli","secrets-manager","2026-11-10 10:12:30",false,"---\nname: aws-secrets-rotation\ndescription: Automate AWS secrets rotation for RDS, API keys, and credentials\nrisk: safe\nsource: community\ncategory: security\ntags: [aws, secrets-manager, security, automation, kiro-cli, credentials]\n---\n\n# AWS Secrets Rotation\n\nAutomate rotation of secrets, credentials, and API keys using AWS Secrets Manager and Lambda.\n\n## When to Use\n\nUse this skill when you need to implement automated secrets rotation, manage credentials securely, or comply with security policies requiring regular key rotation.\n\n## Supported Secret Types\n\n**AWS Services**\n- RDS database credentials\n- DocumentDB credentials\n- Redshift credentials\n- ElastiCache credentials\n\n**Third-Party Services**\n- API keys\n- OAuth tokens\n- SSH keys\n- Custom credentials\n\n## Secrets Manager Setup\n\n### Create a Secret\n\n```bash\n# Create RDS secret\naws secretsmanager create-secret \\\n  --name prod\u002Fdb\u002Fmysql \\\n  --description \"Production MySQL credentials\" \\\n  --secret-string '{\n    \"username\": \"admin\",\n    \"password\": \"CHANGE_ME\",\n    \"engine\": \"mysql\",\n    \"host\": \"mydb.cluster-abc.us-east-1.rds.amazonaws.com\",\n    \"port\": 3306,\n    \"dbname\": \"myapp\"\n  }'\n\n# Create API key secret\naws secretsmanager create-secret \\\n  --name prod\u002Fapi\u002Fstripe \\\n  --secret-string '{\n    \"api_key\": \"sk_live_xxxxx\",\n    \"webhook_secret\": \"whsec_xxxxx\"\n  }'\n\n# Create secret from file\naws secretsmanager create-secret \\\n  --name prod\u002Fssh\u002Fprivate-key \\\n  --secret-binary fileb:\u002F\u002F~\u002F.ssh\u002Fid_rsa\n```\n\n### Retrieve Secrets\n\n```bash\n# Get secret value\naws secretsmanager get-secret-value \\\n  --secret-id prod\u002Fdb\u002Fmysql \\\n  --query 'SecretString' --output text\n\n# Get specific field\naws secretsmanager get-secret-value \\\n  --secret-id prod\u002Fdb\u002Fmysql \\\n  --query 'SecretString' --output text | \\\n  jq -r '.password'\n\n# Get binary secret\naws secretsmanager get-secret-value \\\n  --secret-id prod\u002Fssh\u002Fprivate-key \\\n  --query 'SecretBinary' --output text | \\\n  base64 -d > private-key.pem\n```\n\n## Automatic Rotation Setup\n\n### Enable RDS Rotation\n\n```bash\n# Enable automatic rotation (30 days)\naws secretsmanager rotate-secret \\\n  --secret-id prod\u002Fdb\u002Fmysql \\\n  --rotation-lambda-arn arn:aws:lambda:us-east-1:123456789012:function:SecretsManagerRDSMySQLRotation \\\n  --rotation-rules AutomaticallyAfterDays=30\n\n# Rotate immediately\naws secretsmanager rotate-secret \\\n  --secret-id prod\u002Fdb\u002Fmysql\n\n# Check rotation status\naws secretsmanager describe-secret \\\n  --secret-id prod\u002Fdb\u002Fmysql \\\n  --query 'RotationEnabled'\n```\n\n### Lambda Rotation Function\n\n```python\n# lambda_rotation.py\nimport boto3\nimport json\nimport os\n\nsecrets_client = boto3.client('secretsmanager')\nrds_client = boto3.client('rds')\n\ndef lambda_handler(event, context):\n    \"\"\"Rotate RDS MySQL password\"\"\"\n    \n    secret_arn = event['SecretId']\n    token = event['ClientRequestToken']\n    step = event['Step']\n    \n    # Get current secret\n    current = secrets_client.get_secret_value(SecretId=secret_arn)\n    secret = json.loads(current['SecretString'])\n    \n    if step == \"createSecret\":\n        # Generate new password\n        new_password = generate_password()\n        secret['password'] = new_password\n        \n        # Store as pending\n        secrets_client.put_secret_value(\n            SecretId=secret_arn,\n            ClientRequestToken=token,\n            SecretString=json.dumps(secret),\n            VersionStages=['AWSPENDING']\n        )\n    \n    elif step == \"setSecret\":\n        # Update RDS password\n        rds_client.modify_db_instance(\n            DBInstanceIdentifier=secret['dbInstanceIdentifier'],\n            MasterUserPassword=secret['password'],\n            ApplyImmediately=True\n        )\n    \n    elif step == \"testSecret\":\n        # Test new credentials\n        import pymysql\n        conn = pymysql.connect(\n            host=secret['host'],\n            user=secret['username'],\n            password=secret['password'],\n            database=secret['dbname']\n        )\n        conn.close()\n    \n    elif step == \"finishSecret\":\n        # Mark as current\n        secrets_client.update_secret_version_stage(\n            SecretId=secret_arn,\n            VersionStage='AWSCURRENT',\n            MoveToVersionId=token,\n            RemoveFromVersionId=current['VersionId']\n        )\n    \n    return {'statusCode': 200}\n\ndef generate_password(length=32):\n    import secrets\n    import string\n    alphabet = string.ascii_letters + string.digits + \"!@#$%^&*()\"\n    return ''.join(secrets.choice(alphabet) for _ in range(length))\n```\n\n### Custom Rotation for API Keys\n\n```python\n# api_key_rotation.py\nimport boto3\nimport requests\nimport json\n\nsecrets_client = boto3.client('secretsmanager')\n\ndef rotate_stripe_key(secret_arn, token, step):\n    \"\"\"Rotate Stripe API key\"\"\"\n    \n    current = secrets_client.get_secret_value(SecretId=secret_arn)\n    secret = json.loads(current['SecretString'])\n    \n    if step == \"createSecret\":\n        # Create new Stripe key via API\n        response = requests.post(\n            'https:\u002F\u002Fapi.stripe.com\u002Fv1\u002Fapi_keys',\n            auth=(secret['api_key'], ''),\n            data={'name': f'rotated-{token[:8]}'}\n        )\n        new_key = response.json()['secret']\n        \n        secret['api_key'] = new_key\n        secrets_client.put_secret_value(\n            SecretId=secret_arn,\n            ClientRequestToken=token,\n            SecretString=json.dumps(secret),\n            VersionStages=['AWSPENDING']\n        )\n    \n    elif step == \"testSecret\":\n        # Test new key\n        response = requests.get(\n            'https:\u002F\u002Fapi.stripe.com\u002Fv1\u002Fbalance',\n            auth=(secret['api_key'], '')\n        )\n        if response.status_code != 200:\n            raise Exception(\"New key failed validation\")\n    \n    elif step == \"finishSecret\":\n        # Revoke old key\n        old_key = json.loads(current['SecretString'])['api_key']\n        requests.delete(\n            f'https:\u002F\u002Fapi.stripe.com\u002Fv1\u002Fapi_keys\u002F{old_key}',\n            auth=(secret['api_key'], '')\n        )\n        \n        # Promote to current\n        secrets_client.update_secret_version_stage(\n            SecretId=secret_arn,\n            VersionStage='AWSCURRENT',\n            MoveToVersionId=token\n        )\n```\n\n## Rotation Monitoring\n\n### CloudWatch Alarms\n\n```bash\n# Create alarm for rotation failures\naws cloudwatch put-metric-alarm \\\n  --alarm-name secrets-rotation-failures \\\n  --alarm-description \"Alert on secrets rotation failures\" \\\n  --metric-name RotationFailed \\\n  --namespace AWS\u002FSecretsManager \\\n  --statistic Sum \\\n  --period 300 \\\n  --evaluation-periods 1 \\\n  --threshold 1 \\\n  --comparison-operator GreaterThanThreshold \\\n  --alarm-actions arn:aws:sns:us-east-1:123456789012:alerts\n```\n\n### Rotation Audit Script\n\n```bash\n#!\u002Fbin\u002Fbash\n# audit-rotations.sh\n\necho \"Secrets Rotation Audit\"\necho \"=====================\"\n\naws secretsmanager list-secrets --query 'SecretList[*].[Name,RotationEnabled,LastRotatedDate]' \\\n  --output text | \\\nwhile read name enabled last_rotated; do\n  echo \"\"\n  echo \"Secret: $name\"\n  echo \"  Rotation Enabled: $enabled\"\n  echo \"  Last Rotated: $last_rotated\"\n  \n  if [ \"$enabled\" = \"True\" ]; then\n    # Check rotation schedule\n    rules=$(aws secretsmanager describe-secret --secret-id \"$name\" \\\n      --query 'RotationRules.AutomaticallyAfterDays' --output text)\n    echo \"  Rotation Schedule: Every $rules days\"\n    \n    # Calculate days since last rotation\n    if [ \"$last_rotated\" != \"None\" ]; then\n      days_ago=$(( ($(date +%s) - $(date -d \"$last_rotated\" +%s)) \u002F 86400 ))\n      echo \"  Days Since Rotation: $days_ago\"\n      \n      if [ $days_ago -gt $rules ]; then\n        echo \"  ⚠️  OVERDUE for rotation!\"\n      fi\n    fi\n  fi\ndone\n```\n\n## Application Integration\n\n### Python SDK\n\n```python\nimport boto3\nimport json\n\ndef get_secret(secret_name):\n    \"\"\"Retrieve secret from Secrets Manager\"\"\"\n    client = boto3.client('secretsmanager')\n    \n    try:\n        response = client.get_secret_value(SecretId=secret_name)\n        return json.loads(response['SecretString'])\n    except Exception as e:\n        print(f\"Error retrieving secret: {e}\")\n        raise\n\n# Usage\ndb_creds = get_secret('prod\u002Fdb\u002Fmysql')\nconnection = pymysql.connect(\n    host=db_creds['host'],\n    user=db_creds['username'],\n    password=db_creds['password'],\n    database=db_creds['dbname']\n)\n```\n\n### Node.js SDK\n\n```javascript\nconst AWS = require('aws-sdk');\nconst secretsManager = new AWS.SecretsManager();\n\nasync function getSecret(secretName) {\n  try {\n    const data = await secretsManager.getSecretValue({\n      SecretId: secretName\n    }).promise();\n    \n    return JSON.parse(data.SecretString);\n  } catch (err) {\n    console.error('Error retrieving secret:', err);\n    throw err;\n  }\n}\n\n\u002F\u002F Usage\nconst dbCreds = await getSecret('prod\u002Fdb\u002Fmysql');\nconst connection = mysql.createConnection({\n  host: dbCreds.host,\n  user: dbCreds.username,\n  password: dbCreds.password,\n  database: dbCreds.dbname\n});\n```\n\n## Rotation Best Practices\n\n**Planning**\n- [ ] Identify all secrets requiring rotation\n- [ ] Define rotation schedules (30, 60, 90 days)\n- [ ] Test rotation in non-production first\n- [ ] Document rotation procedures\n- [ ] Plan for emergency rotation\n\n**Implementation**\n- [ ] Use AWS managed rotation when possible\n- [ ] Implement proper error handling\n- [ ] Add CloudWatch monitoring\n- [ ] Test application compatibility\n- [ ] Implement gradual rollout\n\n**Operations**\n- [ ] Monitor rotation success\u002Ffailure\n- [ ] Set up alerts for failures\n- [ ] Regular rotation audits\n- [ ] Document troubleshooting steps\n- [ ] Maintain rotation runbooks\n\n## Emergency Rotation\n\n```bash\n# Immediate rotation (compromise detected)\naws secretsmanager rotate-secret \\\n  --secret-id prod\u002Fdb\u002Fmysql \\\n  --rotate-immediately\n\n# Force rotation even if recently rotated\naws secretsmanager rotate-secret \\\n  --secret-id prod\u002Fapi\u002Fstripe \\\n  --rotation-lambda-arn arn:aws:lambda:us-east-1:123456789012:function:RotateStripeKey \\\n  --rotate-immediately\n\n# Verify rotation completed\naws secretsmanager describe-secret \\\n  --secret-id prod\u002Fdb\u002Fmysql \\\n  --query 'LastRotatedDate'\n```\n\n## Compliance Tracking\n\n```python\n#!\u002Fusr\u002Fbin\u002Fenv python3\n# compliance-report.py\n\nimport boto3\nfrom datetime import datetime, timedelta\n\nclient = boto3.client('secretsmanager')\n\ndef generate_compliance_report():\n    secrets = client.list_secrets()['SecretList']\n    \n    compliant = []\n    non_compliant = []\n    \n    for secret in secrets:\n        name = secret['Name']\n        rotation_enabled = secret.get('RotationEnabled', False)\n        last_rotated = secret.get('LastRotatedDate')\n        \n        if not rotation_enabled:\n            non_compliant.append({\n                'name': name,\n                'issue': 'Rotation not enabled'\n            })\n            continue\n        \n        if last_rotated:\n            days_ago = (datetime.now(last_rotated.tzinfo) - last_rotated).days\n            if days_ago > 90:\n                non_compliant.append({\n                    'name': name,\n                    'issue': f'Not rotated in {days_ago} days'\n                })\n            else:\n                compliant.append(name)\n        else:\n            non_compliant.append({\n                'name': name,\n                'issue': 'Never rotated'\n            })\n    \n    print(f\"Compliant Secrets: {len(compliant)}\")\n    print(f\"Non-Compliant Secrets: {len(non_compliant)}\")\n    print(\"\\nNon-Compliant Details:\")\n    for item in non_compliant:\n        print(f\"  - {item['name']}: {item['issue']}\")\n\nif __name__ == \"__main__\":\n    generate_compliance_report()\n```\n\n## Example Prompts\n\n- \"Set up automatic rotation for my RDS credentials\"\n- \"Create a Lambda function to rotate API keys\"\n- \"Audit all secrets for rotation compliance\"\n- \"Implement emergency rotation for compromised credentials\"\n- \"Generate a secrets rotation report\"\n\n## Kiro CLI Integration\n\n```bash\nkiro-cli chat \"Use aws-secrets-rotation to set up RDS credential rotation\"\nkiro-cli chat \"Create a rotation audit report with aws-secrets-rotation\"\n```\n\n## Additional Resources\n\n- [AWS Secrets Manager Rotation](https:\u002F\u002Fdocs.aws.amazon.com\u002Fsecretsmanager\u002Flatest\u002Fuserguide\u002Frotating-secrets.html)\n- [Rotation Lambda Templates](https:\u002F\u002Fgithub.com\u002Faws-samples\u002Faws-secrets-manager-rotation-lambdas)\n- [Best Practices for Secrets](https:\u002F\u002Fdocs.aws.amazon.com\u002Fsecretsmanager\u002Flatest\u002Fuserguide\u002Fbest-practices.html)\n","# AWS Secrets Rotation\n\nAutomate rotation of secrets, credentials, and API keys using AWS Secrets Manager and Lambda.\n\n## When to Use\n\nUse this skill when you need to implement automated secrets rotation, manage credentials securely, or comply with security policies requiring regular key rotation.\n\n## Supported Secret Types\n\n**AWS Services**\n- RDS database credentials\n- DocumentDB credentials\n- Redshift credentials\n- ElastiCache credentials\n\n**Third-Party Services**\n- API keys\n- OAuth tokens\n- SSH keys\n- Custom credentials\n\n## Secrets Manager Setup\n\n### Create a Secret\n\n```bash\n# Create RDS secret\naws secretsmanager create-secret \\\n  --name prod\u002Fdb\u002Fmysql \\\n  --description \"Production MySQL credentials\" \\\n  --secret-string '{\n    \"username\": \"admin\",\n    \"password\": \"CHANGE_ME\",\n    \"engine\": \"mysql\",\n    \"host\": \"mydb.cluster-abc.us-east-1.rds.amazonaws.com\",\n    \"port\": 3306,\n    \"dbname\": \"myapp\"\n  }'\n\n# Create API key secret\naws secretsmanager create-secret \\\n  --name prod\u002Fapi\u002Fstripe \\\n  --secret-string '{\n    \"api_key\": \"sk_live_xxxxx\",\n    \"webhook_secret\": \"whsec_xxxxx\"\n  }'\n\n# Create secret from file\naws secretsmanager create-secret \\\n  --name prod\u002Fssh\u002Fprivate-key \\\n  --secret-binary fileb:\u002F\u002F~\u002F.ssh\u002Fid_rsa\n```\n\n### Retrieve Secrets\n\n```bash\n# Get secret value\naws secretsmanager get-secret-value \\\n  --secret-id prod\u002Fdb\u002Fmysql \\\n  --query 'SecretString' --output text\n\n# Get specific field\naws secretsmanager get-secret-value \\\n  --secret-id prod\u002Fdb\u002Fmysql \\\n  --query 'SecretString' --output text | \\\n  jq -r '.password'\n\n# Get binary secret\naws secretsmanager get-secret-value \\\n  --secret-id prod\u002Fssh\u002Fprivate-key \\\n  --query 'SecretBinary' --output text | \\\n  base64 -d > private-key.pem\n```\n\n## Automatic Rotation Setup\n\n### Enable RDS Rotation\n\n```bash\n# Enable automatic rotation (30 days)\naws secretsmanager rotate-secret \\\n  --secret-id prod\u002Fdb\u002Fmysql \\\n  --rotation-lambda-arn arn:aws:lambda:us-east-1:123456789012:function:SecretsManagerRDSMySQLRotation \\\n  --rotation-rules AutomaticallyAfterDays=30\n\n# Rotate immediately\naws secretsmanager rotate-secret \\\n  --secret-id prod\u002Fdb\u002Fmysql\n\n# Check rotation status\naws secretsmanager describe-secret \\\n  --secret-id prod\u002Fdb\u002Fmysql \\\n  --query 'RotationEnabled'\n```\n\n### Lambda Rotation Function\n\n```python\n# lambda_rotation.py\nimport boto3\nimport json\nimport os\n\nsecrets_client = boto3.client('secretsmanager')\nrds_client = boto3.client('rds')\n\ndef lambda_handler(event, context):\n    \"\"\"Rotate RDS MySQL password\"\"\"\n    \n    secret_arn = event['SecretId']\n    token = event['ClientRequestToken']\n    step = event['Step']\n    \n    # Get current secret\n    current = secrets_client.get_secret_value(SecretId=secret_arn)\n    secret = json.loads(current['SecretString'])\n    \n    if step == \"createSecret\":\n        # Generate new password\n        new_password = generate_password()\n        secret['password'] = new_password\n        \n        # Store as pending\n        secrets_client.put_secret_value(\n            SecretId=secret_arn,\n            ClientRequestToken=token,\n            SecretString=json.dumps(secret),\n            VersionStages=['AWSPENDING']\n        )\n    \n    elif step == \"setSecret\":\n        # Update RDS password\n        rds_client.modify_db_instance(\n            DBInstanceIdentifier=secret['dbInstanceIdentifier'],\n            MasterUserPassword=secret['password'],\n            ApplyImmediately=True\n        )\n    \n    elif step == \"testSecret\":\n        # Test new credentials\n        import pymysql\n        conn = pymysql.connect(\n            host=secret['host'],\n            user=secret['username'],\n            password=secret['password'],\n            database=secret['dbname']\n        )\n        conn.close()\n    \n    elif step == \"finishSecret\":\n        # Mark as current\n        secrets_client.update_secret_version_stage(\n            SecretId=secret_arn,\n            VersionStage='AWSCURRENT',\n            MoveToVersionId=token,\n            RemoveFromVersionId=current['VersionId']\n        )\n    \n    return {'statusCode': 200}\n\ndef generate_password(length=32):\n    import secrets\n    import string\n    alphabet = string.ascii_letters + string.digits + \"!@#$%^&*()\"\n    return ''.join(secrets.choice(alphabet) for _ in range(length))\n```\n\n### Custom Rotation for API Keys\n\n```python\n# api_key_rotation.py\nimport boto3\nimport requests\nimport json\n\nsecrets_client = boto3.client('secretsmanager')\n\ndef rotate_stripe_key(secret_arn, token, step):\n    \"\"\"Rotate Stripe API key\"\"\"\n    \n    current = secrets_client.get_secret_value(SecretId=secret_arn)\n    secret = json.loads(current['SecretString'])\n    \n    if step == \"createSecret\":\n        # Create new Stripe key via API\n        response = requests.post(\n            'https:\u002F\u002Fapi.stripe.com\u002Fv1\u002Fapi_keys',\n            auth=(secret['api_key'], ''),\n            data={'name': f'rotated-{token[:8]}'}\n        )\n        new_key = response.json()['secret']\n        \n        secret['api_key'] = new_key\n        secrets_client.put_secret_value(\n            SecretId=secret_arn,\n            ClientRequestToken=token,\n            SecretString=json.dumps(secret),\n            VersionStages=['AWSPENDING']\n        )\n    \n    elif step == \"testSecret\":\n        # Test new key\n        response = requests.get(\n            'https:\u002F\u002Fapi.stripe.com\u002Fv1\u002Fbalance',\n            auth=(secret['api_key'], '')\n        )\n        if response.status_code != 200:\n            raise Exception(\"New key failed validation\")\n    \n    elif step == \"finishSecret\":\n        # Revoke old key\n        old_key = json.loads(current['SecretString'])['api_key']\n        requests.delete(\n            f'https:\u002F\u002Fapi.stripe.com\u002Fv1\u002Fapi_keys\u002F{old_key}',\n            auth=(secret['api_key'], '')\n        )\n        \n        # Promote to current\n        secrets_client.update_secret_version_stage(\n            SecretId=secret_arn,\n            VersionStage='AWSCURRENT',\n            MoveToVersionId=token\n        )\n```\n\n## Rotation Monitoring\n\n### CloudWatch Alarms\n\n```bash\n# Create alarm for rotation failures\naws cloudwatch put-metric-alarm \\\n  --alarm-name secrets-rotation-failures \\\n  --alarm-description \"Alert on secrets rotation failures\" \\\n  --metric-name RotationFailed \\\n  --namespace AWS\u002FSecretsManager \\\n  --statistic Sum \\\n  --period 300 \\\n  --evaluation-periods 1 \\\n  --threshold 1 \\\n  --comparison-operator GreaterThanThreshold \\\n  --alarm-actions arn:aws:sns:us-east-1:123456789012:alerts\n```\n\n### Rotation Audit Script\n\n```bash\n#!\u002Fbin\u002Fbash\n# audit-rotations.sh\n\necho \"Secrets Rotation Audit\"\necho \"=====================\"\n\naws secretsmanager list-secrets --query 'SecretList[*].[Name,RotationEnabled,LastRotatedDate]' \\\n  --output text | \\\nwhile read name enabled last_rotated; do\n  echo \"\"\n  echo \"Secret: $name\"\n  echo \"  Rotation Enabled: $enabled\"\n  echo \"  Last Rotated: $last_rotated\"\n  \n  if [ \"$enabled\" = \"True\" ]; then\n    # Check rotation schedule\n    rules=$(aws secretsmanager describe-secret --secret-id \"$name\" \\\n      --query 'RotationRules.AutomaticallyAfterDays' --output text)\n    echo \"  Rotation Schedule: Every $rules days\"\n    \n    # Calculate days since last rotation\n    if [ \"$last_rotated\" != \"None\" ]; then\n      days_ago=$(( ($(date +%s) - $(date -d \"$last_rotated\" +%s)) \u002F 86400 ))\n      echo \"  Days Since Rotation: $days_ago\"\n      \n      if [ $days_ago -gt $rules ]; then\n        echo \"  ⚠️  OVERDUE for rotation!\"\n      fi\n    fi\n  fi\ndone\n```\n\n## Application Integration\n\n### Python SDK\n\n```python\nimport boto3\nimport json\n\ndef get_secret(secret_name):\n    \"\"\"Retrieve secret from Secrets Manager\"\"\"\n    client = boto3.client('secretsmanager')\n    \n    try:\n        response = client.get_secret_value(SecretId=secret_name)\n        return json.loads(response['SecretString'])\n    except Exception as e:\n        print(f\"Error retrieving secret: {e}\")\n        raise\n\n# Usage\ndb_creds = get_secret('prod\u002Fdb\u002Fmysql')\nconnection = pymysql.connect(\n    host=db_creds['host'],\n    user=db_creds['username'],\n    password=db_creds['password'],\n    database=db_creds['dbname']\n)\n```\n\n### Node.js SDK\n\n```javascript\nconst AWS = require('aws-sdk');\nconst secretsManager = new AWS.SecretsManager();\n\nasync function getSecret(secretName) {\n  try {\n    const data = await secretsManager.getSecretValue({\n      SecretId: secretName\n    }).promise();\n    \n    return JSON.parse(data.SecretString);\n  } catch (err) {\n    console.error('Error retrieving secret:', err);\n    throw err;\n  }\n}\n\n\u002F\u002F Usage\nconst dbCreds = await getSecret('prod\u002Fdb\u002Fmysql');\nconst connection = mysql.createConnection({\n  host: dbCreds.host,\n  user: dbCreds.username,\n  password: dbCreds.password,\n  database: dbCreds.dbname\n});\n```\n\n## Rotation Best Practices\n\n**Planning**\n- [ ] Identify all secrets requiring rotation\n- [ ] Define rotation schedules (30, 60, 90 days)\n- [ ] Test rotation in non-production first\n- [ ] Document rotation procedures\n- [ ] Plan for emergency rotation\n\n**Implementation**\n- [ ] Use AWS managed rotation when possible\n- [ ] Implement proper error handling\n- [ ] Add CloudWatch monitoring\n- [ ] Test application compatibility\n- [ ] Implement gradual rollout\n\n**Operations**\n- [ ] Monitor rotation success\u002Ffailure\n- [ ] Set up alerts for failures\n- [ ] Regular rotation audits\n- [ ] Document troubleshooting steps\n- [ ] Maintain rotation runbooks\n\n## Emergency Rotation\n\n```bash\n# Immediate rotation (compromise detected)\naws secretsmanager rotate-secret \\\n  --secret-id prod\u002Fdb\u002Fmysql \\\n  --rotate-immediately\n\n# Force rotation even if recently rotated\naws secretsmanager rotate-secret \\\n  --secret-id prod\u002Fapi\u002Fstripe \\\n  --rotation-lambda-arn arn:aws:lambda:us-east-1:123456789012:function:RotateStripeKey \\\n  --rotate-immediately\n\n# Verify rotation completed\naws secretsmanager describe-secret \\\n  --secret-id prod\u002Fdb\u002Fmysql \\\n  --query 'LastRotatedDate'\n```\n\n## Compliance Tracking\n\n```python\n#!\u002Fusr\u002Fbin\u002Fenv python3\n# compliance-report.py\n\nimport boto3\nfrom datetime import datetime, timedelta\n\nclient = boto3.client('secretsmanager')\n\ndef generate_compliance_report():\n    secrets = client.list_secrets()['SecretList']\n    \n    compliant = []\n    non_compliant = []\n    \n    for secret in secrets:\n        name = secret['Name']\n        rotation_enabled = secret.get('RotationEnabled', False)\n        last_rotated = secret.get('LastRotatedDate')\n        \n        if not rotation_enabled:\n            non_compliant.append({\n                'name': name,\n                'issue': 'Rotation not enabled'\n            })\n            continue\n        \n        if last_rotated:\n            days_ago = (datetime.now(last_rotated.tzinfo) - last_rotated).days\n            if days_ago > 90:\n                non_compliant.append({\n                    'name': name,\n                    'issue': f'Not rotated in {days_ago} days'\n                })\n            else:\n                compliant.append(name)\n        else:\n            non_compliant.append({\n                'name': name,\n                'issue': 'Never rotated'\n            })\n    \n    print(f\"Compliant Secrets: {len(compliant)}\")\n    print(f\"Non-Compliant Secrets: {len(non_compliant)}\")\n    print(\"\\nNon-Compliant Details:\")\n    for item in non_compliant:\n        print(f\"  - {item['name']}: {item['issue']}\")\n\nif __name__ == \"__main__\":\n    generate_compliance_report()\n```\n\n## Example Prompts\n\n- \"Set up automatic rotation for my RDS credentials\"\n- \"Create a Lambda function to rotate API keys\"\n- \"Audit all secrets for rotation compliance\"\n- \"Implement emergency rotation for compromised credentials\"\n- \"Generate a secrets rotation report\"\n\n## Kiro CLI Integration\n\n```bash\nkiro-cli chat \"Use aws-secrets-rotation to set up RDS credential rotation\"\nkiro-cli chat \"Create a rotation audit report with aws-secrets-rotation\"\n```\n\n## Additional Resources\n\n- [AWS Secrets Manager Rotation](https:\u002F\u002Fdocs.aws.amazon.com\u002Fsecretsmanager\u002Flatest\u002Fuserguide\u002Frotating-secrets.html)\n- [Rotation Lambda Templates](https:\u002F\u002Fgithub.com\u002Faws-samples\u002Faws-secrets-manager-rotation-lambdas)\n- [Best Practices for Secrets](https:\u002F\u002Fdocs.aws.amazon.com\u002Fsecretsmanager\u002Flatest\u002Fuserguide\u002Fbest-practices.html)\n",{"name":5,"risk":33,"tags":48,"source":39,"category":34,"description":7},[29,42,34,35,41,36],"main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002Faiskillstore\u002Fmarketplace\u002Fsickn33\u002Faws-secrets-rotation",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":8,"skillName":5,"commands":59,"prompt":69,"zipAvailable":70},[60,63,66],{"tool":61,"command":62},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill aws-secrets-rotation",{"tool":64,"command":65},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill aws-secrets-rotation",{"tool":67,"command":68},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill aws-secrets-rotation","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fsickn33\u002Faws-secrets-rotation\u002FSKILL.md",true,[72],{"path":73,"resourceType":74,"resourceTypeDesc":75,"sizeBytes":76,"sourceHtmlUrl":77},"skill-report.json","REFERENCE","参考文档",8438,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fsickn33\u002Faws-secrets-rotation\u002Fskill-report.json",[79,89,99,108,114,121],{"skillNo":80,"name":81,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":82,"categories":83,"keywords":85,"publishedAt":43},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[84],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[86,87,88],"model","model hierarchy","model hierarchy skill",{"skillNo":90,"name":91,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":92,"categories":93,"keywords":95,"publishedAt":43},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[94],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[96,97,98],"MCP","zoom","zoom mcp",{"skillNo":100,"name":101,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":102,"categories":103,"keywords":104,"publishedAt":43},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[105,106,107,97],"sdk","zoom apps sdk","apps",{"skillNo":109,"name":110,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":111,"categories":112,"keywords":113,"publishedAt":43},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[110],{"skillNo":115,"name":116,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":117,"categories":118,"keywords":120,"publishedAt":43},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[119],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[116],{"skillNo":122,"name":123,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":124,"categories":125,"keywords":126,"publishedAt":43},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[123]]