secrets-manager
AWS Secrets Manager for secure secret storage and rotation. Use when storing credentials, configuring automatic rotation, managing secret versions, retrieving secrets in applications, or integrating with RDS.
Install
npx skills add https://github.com/itsmostafa/aws-agent-skills/tree/main/skills/secrets-manager
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install itsmostafa-aws-agent-skills@llmmart
git clone https://github.com/itsmostafa/aws-agent-skills.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole itsmostafa/aws-agent-skills collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
AWS Secrets Manager
AWS Secrets Manager helps protect access to applications, services, and IT resources. Store, retrieve, and automatically rotate credentials, API keys, and other secrets.
Table of Contents
Core Concepts
Secrets
Encrypted data stored in Secrets Manager. Can contain:
- Database credentials
- API keys
- OAuth tokens
- Any key-value pairs (up to 64 KB)
Versions
Each secret can have multiple versions:
- AWSCURRENT: Current active version
- AWSPENDING: Version being rotated to
- AWSPREVIOUS: Previous version
Rotation
Automatic credential rotation using Lambda functions. Built-in support for:
- Amazon RDS
- Amazon Redshift
- Amazon DocumentDB
- Custom secrets
Common Patterns
Create a Secret
AWS CLI:
# Create secret with JSON
aws secretsmanager create-secret \
--name prod/myapp/database \
--description "Production database credentials" \
--secret-string '{"username":"admin","password":"MySecurePassword123!","host":"mydb.cluster-xyz.us-east-1.rds.amazonaws.com","port":5432,"database":"myapp"}'
# Create secret with binary data
aws secretsmanager create-secret \
--name prod/myapp/certificate \
--secret-binary fileb://certificate.pem
boto3:
import boto3
import json
secrets = boto3.client('secretsmanager')
response = secrets.create_secret(
Name='prod/myapp/database',
Description='Production database credentials',
SecretString=json.dumps({
'username': 'admin',
'password': 'MySecurePassword123!',
'host': 'mydb.cluster-xyz.us-east-1.rds.amazonaws.com',
'port': 5432,
'database': 'myapp'
}),
Tags=[
{'Key': 'Environment', 'Value': 'production'},
{'Key': 'Application', 'Value': 'myapp'}
]
)
Retrieve a Secret
import boto3
import json
secrets = boto3.client('secretsmanager')
def get_secret(secret_name):
response = secrets.get_secret_value(SecretId=secret_name)
if 'SecretString' in response:
return json.loads(response['SecretString'])
else:
import base64
return base64.b64decode(response['SecretBinary'])
# Usage
credentials = get_secret('prod/myapp/database')
db_password = credentials['password']
Caching Secrets
from aws_secretsmanager_caching import SecretCache, SecretCacheConfig
# Configure cache
cache_config = SecretCacheConfig(
max_cache_size=100,
secret_refresh_interval=3600,
secret_version_stage_refresh_interval=3600
)
cache = SecretCache(config=cache_config)
def get_cached_secret(secret_name):
secret = cache.get_secret_string(secret_name)
return json.loads(secret)
Update a Secret
# Update secret value
aws secretsmanager update-secret \
--secret-id prod/myapp/database \
--secret-string '{"username":"admin","password":"NewPassword456!"}'
# Put new version with staging labels
aws secretsmanager put-secret-value \
--secret-id prod/myapp/database \
--secret-string '{"username":"admin","password":"NewPassword456!"}' \
--version-stages AWSCURRENT
Enable Rotation for RDS
aws secretsmanager rotate-secret \
--secret-id prod/myapp/database \
--rotation-lambda-arn arn:aws:lambda:us-east-1:123456789012:function:SecretsManagerRDSPostgreSQLRotation \
--rotation-rules AutomaticallyAfterDays=30
Create Secret with Rotation
# Use CloudFormation for RDS secret with rotation
aws cloudformation deploy \
--template-file rds-secret.yaml \
--stack-name rds-secret
# rds-secret.yaml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
DBSecret:
Type: AWS::SecretsManager::Secret
Properties:
Name: prod/myapp/database
GenerateSecretString:
SecretStringTemplate: '{"username": "admin"}'
GenerateStringKey: password
PasswordLength: 32
ExcludeCharacters: '"@/\'
DBSecretRotation:
Type: AWS::SecretsManager::RotationSchedule
Properties:
SecretId: !Ref DBSecret
RotationLambdaARN: !GetAtt RotationLambda.Arn
RotationRules:
AutomaticallyAfterDays: 30
Use in Lambda with Extension
import json
import urllib.request
def handler(event, context):
# Use AWS Parameters and Secrets Lambda Extension
secrets_port = 2773
secret_name = 'prod/myapp/database'
url = f'http://localhost:{secrets_port}/secretsmanager/get?secretId={secret_name}'
headers = {'X-Aws-Parameters-Secrets-Token': os.environ['AWS_SESSION_TOKEN']}
request = urllib.request.Request(url, headers=headers)
response = urllib.request.urlopen(request)
secret = json.loads(response.read())['SecretString']
credentials = json.loads(secret)
return credentials
CLI Reference
Secret Management
| Command | Description |
|---|---|
aws secretsmanager create-secret |
Create secret |
aws secretsmanager describe-secret |
Get secret metadata |
aws secretsmanager get-secret-value |
Retrieve secret value |
aws secretsmanager update-secret |
Update secret |
aws secretsmanager delete-secret |
Delete secret |
aws secretsmanager restore-secret |
Restore deleted secret |
aws secretsmanager list-secrets |
List secrets |
Versions
| Command | Description |
|---|---|
aws secretsmanager put-secret-value |
Add new version |
aws secretsmanager list-secret-version-ids |
List versions |
aws secretsmanager update-secret-version-stage |
Move staging labels |
Rotation
| Command | Description |
|---|---|
aws secretsmanager rotate-secret |
Configure/trigger rotation |
aws secretsmanager cancel-rotate-secret |
Cancel rotation |
Best Practices
Secret Organization
- Use hierarchical names:
environment/application/secret-type - Tag secrets for organization and cost allocation
- Separate by environment (dev, staging, prod)
Security
- Use resource policies to control access
- Enable encryption with customer-managed KMS keys
- Rotate secrets regularly (30-90 days)
- Audit access with CloudTrail
- Use VPC endpoints for private access
Access Control
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret"
],
"Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/*",
"Condition": {
"StringEquals": {
"secretsmanager:ResourceTag/Environment": "production"
}
}
}
]
}
Application Integration
- Cache secrets to reduce API calls
- Handle rotation gracefully (retry with new credentials)
- Use Lambda extension for faster access
- Never log secrets
Troubleshooting
AccessDeniedException
Causes:
- IAM policy missing
secretsmanager:GetSecretValue - Resource policy denying access
- KMS key policy missing permissions
Debug:
# Check secret resource policy
aws secretsmanager get-resource-policy --secret-id my-secret
# Check IAM permissions
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789012:role/my-role \
--action-names secretsmanager:GetSecretValue \
--resource-arns arn:aws:secretsmanager:us-east-1:123456789012:secret:my-secret
Rotation Failed
Debug:
# Check rotation status
aws secretsmanager describe-secret --secret-id my-secret
# Check Lambda logs
aws logs filter-log-events \
--log-group-name /aws/lambda/SecretsManagerRotation \
--filter-pattern "ERROR"
Common causes:
- Lambda timeout (increase to 30+ seconds)
- Network connectivity (VPC configuration)
- Database connection issues
- Wrong secret format
Secret Not Found
# List secrets to find correct name
aws secretsmanager list-secrets \
--filters Key=name,Values=myapp
# Check if deleted (within recovery window)
aws secretsmanager list-secrets \
--include-planned-deletion
References
Files (aws-agent-skills)
-
rotation-strategies.md 10.9 KB
# Secrets Manager Rotation Strategies Secret rotation patterns and Lambda rotation functions. ## Rotation Strategies ### Single User Rotation One user, password changes in place. Brief connection interruption during rotation. ``` 1. AWSCURRENT has current password 2. Lambda creates new password → AWSPENDING 3. Lambda updates database with new password 4. Lambda tests AWSPENDING credentials 5. Lambda moves AWSPENDING → AWSCURRENT ``` ### Alternating Users Rotation Two users alternate, zero downtime. ``` User A (AWSCURRENT) → User B (AWSPENDING) 1. Lambda creates new password for User B 2. Lambda updates User B in database 3. Lambda tests User B credentials 4. Lambda moves User B → AWSCURRENT 5. Next rotation: User A becomes AWSPENDING ``` ## Built-in Rotation Functions ### RDS PostgreSQL ```bash # Use AWS-provided rotation Lambda aws secretsmanager rotate-secret \ --secret-id prod/myapp/database \ --rotation-lambda-arn arn:aws:lambda:us-east-1:123456789012:function:SecretsManagerRDSPostgreSQLRotationSingleUser \ --rotation-rules AutomaticallyAfterDays=30 ``` ### RDS MySQL ```bash aws secretsmanager rotate-secret \ --secret-id prod/myapp/database \ --rotation-lambda-arn arn:aws:lambda:us-east-1:123456789012:function:SecretsManagerRDSMySQLRotationSingleUser \ --rotation-rules AutomaticallyAfterDays=30 ``` ### Deploy Rotation Lambda ```bash # Use SAR to deploy rotation function aws serverlessrepo create-cloud-formation-change-set \ --application-id arn:aws:serverlessrepo:us-east-1:297356227824:applications/SecretsManagerRDSPostgreSQLRotationSingleUser \ --stack-name rds-rotation-lambda \ --capabilities CAPABILITY_IAM \ --parameter-overrides \ Name=endpoint,Value=mydb.cluster-xyz.us-east-1.rds.amazonaws.com \ Name=functionName,Value=SecretsManagerRDSPostgreSQLRotation ``` ## Custom Rotation Lambda ### Lambda Structure ```python import boto3 import json import logging logger = logging.getLogger() logger.setLevel(logging.INFO) secrets = boto3.client('secretsmanager') def handler(event, context): secret_id = event['SecretId'] token = event['ClientRequestToken'] step = event['Step'] if step == 'createSecret': create_secret(secret_id, token) elif step == 'setSecret': set_secret(secret_id, token) elif step == 'testSecret': test_secret(secret_id, token) elif step == 'finishSecret': finish_secret(secret_id, token) else: raise ValueError(f'Unknown step: {step}') def create_secret(secret_id, token): """Create new secret version with AWSPENDING label.""" # Check if already exists try: secrets.get_secret_value( SecretId=secret_id, VersionId=token, VersionStage='AWSPENDING' ) logger.info('AWSPENDING already exists') return except secrets.exceptions.ResourceNotFoundException: pass # Get current secret current = secrets.get_secret_value( SecretId=secret_id, VersionStage='AWSCURRENT' ) current_secret = json.loads(current['SecretString']) # Generate new password new_password = secrets.get_random_password( PasswordLength=32, ExcludeCharacters='"@/\\' )['RandomPassword'] # Create new version new_secret = current_secret.copy() new_secret['password'] = new_password secrets.put_secret_value( SecretId=secret_id, ClientRequestToken=token, SecretString=json.dumps(new_secret), VersionStages=['AWSPENDING'] ) def set_secret(secret_id, token): """Update the resource with the new credentials.""" pending = secrets.get_secret_value( SecretId=secret_id, VersionId=token, VersionStage='AWSPENDING' ) pending_secret = json.loads(pending['SecretString']) # Update the actual resource (e.g., API key in external service) # This is where you'd call your service's API to update the credential update_resource_credential(pending_secret) def test_secret(secret_id, token): """Test that the new credentials work.""" pending = secrets.get_secret_value( SecretId=secret_id, VersionId=token, VersionStage='AWSPENDING' ) pending_secret = json.loads(pending['SecretString']) # Test the credentials if not verify_credentials_work(pending_secret): raise ValueError('New credentials failed validation') def finish_secret(secret_id, token): """Finalize rotation by moving labels.""" # Get current version metadata = secrets.describe_secret(SecretId=secret_id) current_version = None for version_id, stages in metadata['VersionIdsToStages'].items(): if 'AWSCURRENT' in stages: current_version = version_id break # Move AWSCURRENT to new version secrets.update_secret_version_stage( SecretId=secret_id, VersionStage='AWSCURRENT', MoveToVersionId=token, RemoveFromVersionId=current_version ) ``` ### API Key Rotation Example ```python import boto3 import json import requests secrets = boto3.client('secretsmanager') def set_secret(secret_id, token): """Rotate API key in external service.""" # Get pending secret pending = secrets.get_secret_value( SecretId=secret_id, VersionId=token, VersionStage='AWSPENDING' ) pending_secret = json.loads(pending['SecretString']) # Get current secret (for authentication) current = secrets.get_secret_value( SecretId=secret_id, VersionStage='AWSCURRENT' ) current_secret = json.loads(current['SecretString']) # Call external API to create new key response = requests.post( 'https://api.example.com/v1/api-keys/rotate', headers={'Authorization': f'Bearer {current_secret["api_key"]}'}, json={'new_key': pending_secret['api_key']} ) if response.status_code != 200: raise Exception(f'Failed to rotate API key: {response.text}') def test_secret(secret_id, token): """Test new API key works.""" pending = secrets.get_secret_value( SecretId=secret_id, VersionId=token, VersionStage='AWSPENDING' ) pending_secret = json.loads(pending['SecretString']) response = requests.get( 'https://api.example.com/v1/me', headers={'Authorization': f'Bearer {pending_secret["api_key"]}'} ) if response.status_code != 200: raise Exception('New API key validation failed') ``` ## VPC Configuration For RDS rotation, Lambda needs VPC access: ```yaml Resources: RotationLambda: Type: AWS::Lambda::Function Properties: VpcConfig: SecurityGroupIds: - !Ref LambdaSecurityGroup SubnetIds: - !Ref PrivateSubnet1 - !Ref PrivateSubnet2 LambdaSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: VpcId: !Ref VPC SecurityGroupEgress: - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 0.0.0.0/0 # For Secrets Manager API - IpProtocol: tcp FromPort: 5432 ToPort: 5432 DestinationSecurityGroupId: !Ref DBSecurityGroup # VPC Endpoint for Secrets Manager SecretsManagerEndpoint: Type: AWS::EC2::VPCEndpoint Properties: VpcId: !Ref VPC ServiceName: !Sub com.amazonaws.${AWS::Region}.secretsmanager VpcEndpointType: Interface SubnetIds: - !Ref PrivateSubnet1 - !Ref PrivateSubnet2 SecurityGroupIds: - !Ref EndpointSecurityGroup ``` ## Rotation Permissions ### Lambda Execution Role ```json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret", "secretsmanager:PutSecretValue", "secretsmanager:UpdateSecretVersionStage" ], "Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/*" }, { "Effect": "Allow", "Action": "secretsmanager:GetRandomPassword", "Resource": "*" }, { "Effect": "Allow", "Action": [ "kms:Decrypt", "kms:GenerateDataKey" ], "Resource": "arn:aws:kms:us-east-1:123456789012:key/..." } ] } ``` ### Secret Resource Policy ```json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::123456789012:role/rotation-lambda-role" }, "Action": [ "secretsmanager:GetSecretValue", "secretsmanager:PutSecretValue", "secretsmanager:UpdateSecretVersionStage" ], "Resource": "*", "Condition": { "StringEquals": { "secretsmanager:VersionStage": ["AWSCURRENT", "AWSPENDING"] } } } ] } ``` ## Handling Rotation in Applications ### Retry with New Credentials ```python import boto3 import json import psycopg2 from functools import wraps secrets = boto3.client('secretsmanager') _cached_secret = None _secret_version = None def get_db_credentials(): global _cached_secret, _secret_version response = secrets.get_secret_value(SecretId='prod/myapp/database') if response['VersionId'] != _secret_version: _cached_secret = json.loads(response['SecretString']) _secret_version = response['VersionId'] return _cached_secret def with_credential_refresh(func): @wraps(func) def wrapper(*args, **kwargs): try: return func(*args, **kwargs) except psycopg2.OperationalError as e: if 'authentication failed' in str(e).lower(): # Force refresh and retry global _cached_secret, _secret_version _cached_secret = None _secret_version = None return func(*args, **kwargs) raise return wrapper @with_credential_refresh def query_database(): creds = get_db_credentials() conn = psycopg2.connect( host=creds['host'], port=creds['port'], database=creds['database'], user=creds['username'], password=creds['password'] ) # Execute query... ``` ## Monitoring Rotation ### CloudWatch Alarms ```bash # Alarm for rotation failures aws cloudwatch put-metric-alarm \ --alarm-name SecretsRotationFailed \ --metric-name RotationFailure \ --namespace AWS/SecretsManager \ --statistic Sum \ --period 86400 \ --threshold 1 \ --comparison-operator GreaterThanOrEqualToThreshold \ --evaluation-periods 1 \ --alarm-actions arn:aws:sns:us-east-1:123456789012:alerts # Alarm for secrets not rotated aws cloudwatch put-metric-alarm \ --alarm-name SecretsNotRotated \ --metric-name DaysSinceLastRotation \ --namespace AWS/SecretsManager \ --dimensions Name=SecretName,Value=prod/myapp/database \ --statistic Maximum \ --period 86400 \ --threshold 45 \ --comparison-operator GreaterThanThreshold \ --evaluation-periods 1 \ --alarm-actions arn:aws:sns:us-east-1:123456789012:alerts ``` -
SKILL.md 8.8 KB
--- name: secrets-manager description: AWS Secrets Manager for secure secret storage and rotation. Use when storing credentials, configuring automatic rotation, managing secret versions, retrieving secrets in applications, or integrating with RDS. last_updated: "2026-01-07" doc_source: https://docs.aws.amazon.com/secretsmanager/latest/userguide/ --- # AWS Secrets Manager AWS Secrets Manager helps protect access to applications, services, and IT resources. Store, retrieve, and automatically rotate credentials, API keys, and other secrets. ## Table of Contents - [Core Concepts](#core-concepts) - [Common Patterns](#common-patterns) - [CLI Reference](#cli-reference) - [Best Practices](#best-practices) - [Troubleshooting](#troubleshooting) - [References](#references) ## Core Concepts ### Secrets Encrypted data stored in Secrets Manager. Can contain: - Database credentials - API keys - OAuth tokens - Any key-value pairs (up to 64 KB) ### Versions Each secret can have multiple versions: - **AWSCURRENT**: Current active version - **AWSPENDING**: Version being rotated to - **AWSPREVIOUS**: Previous version ### Rotation Automatic credential rotation using Lambda functions. Built-in support for: - Amazon RDS - Amazon Redshift - Amazon DocumentDB - Custom secrets ## Common Patterns ### Create a Secret **AWS CLI:** ```bash # Create secret with JSON aws secretsmanager create-secret \ --name prod/myapp/database \ --description "Production database credentials" \ --secret-string '{"username":"admin","password":"MySecurePassword123!","host":"mydb.cluster-xyz.us-east-1.rds.amazonaws.com","port":5432,"database":"myapp"}' # Create secret with binary data aws secretsmanager create-secret \ --name prod/myapp/certificate \ --secret-binary fileb://certificate.pem ``` **boto3:** ```python import boto3 import json secrets = boto3.client('secretsmanager') response = secrets.create_secret( Name='prod/myapp/database', Description='Production database credentials', SecretString=json.dumps({ 'username': 'admin', 'password': 'MySecurePassword123!', 'host': 'mydb.cluster-xyz.us-east-1.rds.amazonaws.com', 'port': 5432, 'database': 'myapp' }), Tags=[ {'Key': 'Environment', 'Value': 'production'}, {'Key': 'Application', 'Value': 'myapp'} ] ) ``` ### Retrieve a Secret ```python import boto3 import json secrets = boto3.client('secretsmanager') def get_secret(secret_name): response = secrets.get_secret_value(SecretId=secret_name) if 'SecretString' in response: return json.loads(response['SecretString']) else: import base64 return base64.b64decode(response['SecretBinary']) # Usage credentials = get_secret('prod/myapp/database') db_password = credentials['password'] ``` ### Caching Secrets ```python from aws_secretsmanager_caching import SecretCache, SecretCacheConfig # Configure cache cache_config = SecretCacheConfig( max_cache_size=100, secret_refresh_interval=3600, secret_version_stage_refresh_interval=3600 ) cache = SecretCache(config=cache_config) def get_cached_secret(secret_name): secret = cache.get_secret_string(secret_name) return json.loads(secret) ``` ### Update a Secret ```bash # Update secret value aws secretsmanager update-secret \ --secret-id prod/myapp/database \ --secret-string '{"username":"admin","password":"NewPassword456!"}' # Put new version with staging labels aws secretsmanager put-secret-value \ --secret-id prod/myapp/database \ --secret-string '{"username":"admin","password":"NewPassword456!"}' \ --version-stages AWSCURRENT ``` ### Enable Rotation for RDS ```bash aws secretsmanager rotate-secret \ --secret-id prod/myapp/database \ --rotation-lambda-arn arn:aws:lambda:us-east-1:123456789012:function:SecretsManagerRDSPostgreSQLRotation \ --rotation-rules AutomaticallyAfterDays=30 ``` ### Create Secret with Rotation ```bash # Use CloudFormation for RDS secret with rotation aws cloudformation deploy \ --template-file rds-secret.yaml \ --stack-name rds-secret ``` ```yaml # rds-secret.yaml AWSTemplateFormatVersion: '2010-09-09' Resources: DBSecret: Type: AWS::SecretsManager::Secret Properties: Name: prod/myapp/database GenerateSecretString: SecretStringTemplate: '{"username": "admin"}' GenerateStringKey: password PasswordLength: 32 ExcludeCharacters: '"@/\' DBSecretRotation: Type: AWS::SecretsManager::RotationSchedule Properties: SecretId: !Ref DBSecret RotationLambdaARN: !GetAtt RotationLambda.Arn RotationRules: AutomaticallyAfterDays: 30 ``` ### Use in Lambda with Extension ```python import json import urllib.request def handler(event, context): # Use AWS Parameters and Secrets Lambda Extension secrets_port = 2773 secret_name = 'prod/myapp/database' url = f'http://localhost:{secrets_port}/secretsmanager/get?secretId={secret_name}' headers = {'X-Aws-Parameters-Secrets-Token': os.environ['AWS_SESSION_TOKEN']} request = urllib.request.Request(url, headers=headers) response = urllib.request.urlopen(request) secret = json.loads(response.read())['SecretString'] credentials = json.loads(secret) return credentials ``` ## CLI Reference ### Secret Management | Command | Description | |---------|-------------| | `aws secretsmanager create-secret` | Create secret | | `aws secretsmanager describe-secret` | Get secret metadata | | `aws secretsmanager get-secret-value` | Retrieve secret value | | `aws secretsmanager update-secret` | Update secret | | `aws secretsmanager delete-secret` | Delete secret | | `aws secretsmanager restore-secret` | Restore deleted secret | | `aws secretsmanager list-secrets` | List secrets | ### Versions | Command | Description | |---------|-------------| | `aws secretsmanager put-secret-value` | Add new version | | `aws secretsmanager list-secret-version-ids` | List versions | | `aws secretsmanager update-secret-version-stage` | Move staging labels | ### Rotation | Command | Description | |---------|-------------| | `aws secretsmanager rotate-secret` | Configure/trigger rotation | | `aws secretsmanager cancel-rotate-secret` | Cancel rotation | ## Best Practices ### Secret Organization - **Use hierarchical names**: `environment/application/secret-type` - **Tag secrets** for organization and cost allocation - **Separate by environment** (dev, staging, prod) ### Security - **Use resource policies** to control access - **Enable encryption** with customer-managed KMS keys - **Rotate secrets** regularly (30-90 days) - **Audit access** with CloudTrail - **Use VPC endpoints** for private access ### Access Control ```json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret" ], "Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/*", "Condition": { "StringEquals": { "secretsmanager:ResourceTag/Environment": "production" } } } ] } ``` ### Application Integration - **Cache secrets** to reduce API calls - **Handle rotation** gracefully (retry with new credentials) - **Use Lambda extension** for faster access - **Never log secrets** ## Troubleshooting ### AccessDeniedException **Causes:** - IAM policy missing `secretsmanager:GetSecretValue` - Resource policy denying access - KMS key policy missing permissions **Debug:** ```bash # Check secret resource policy aws secretsmanager get-resource-policy --secret-id my-secret # Check IAM permissions aws iam simulate-principal-policy \ --policy-source-arn arn:aws:iam::123456789012:role/my-role \ --action-names secretsmanager:GetSecretValue \ --resource-arns arn:aws:secretsmanager:us-east-1:123456789012:secret:my-secret ``` ### Rotation Failed **Debug:** ```bash # Check rotation status aws secretsmanager describe-secret --secret-id my-secret # Check Lambda logs aws logs filter-log-events \ --log-group-name /aws/lambda/SecretsManagerRotation \ --filter-pattern "ERROR" ``` **Common causes:** - Lambda timeout (increase to 30+ seconds) - Network connectivity (VPC configuration) - Database connection issues - Wrong secret format ### Secret Not Found ```bash # List secrets to find correct name aws secretsmanager list-secrets \ --filters Key=name,Values=myapp # Check if deleted (within recovery window) aws secretsmanager list-secrets \ --include-planned-deletion ``` ## References - [Secrets Manager User Guide](https://docs.aws.amazon.com/secretsmanager/latest/userguide/) - [Secrets Manager API Reference](https://docs.aws.amazon.com/secretsmanager/latest/apireference/) - [Secrets Manager CLI Reference](https://docs.aws.amazon.com/cli/latest/reference/secretsmanager/) - [boto3 Secrets Manager](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/secretsmanager.html)
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.