Back to skills
SKILL.md
Aws Secrets
ASecurityExpert agent for AWS Secrets Manager and AWS KMS. Covers secret rotation (Lambda, native RDS), multi-region replication, resource policies, versioning (AWSCURRENT/AWSPREVIOUS), KMS key hierarchy, CMK, grants, key policies, envelope encryption, and multi-region keys. WHEN: \"AWS Secrets Manager\", \"AWS KMS\", \"secret rotation\", \"RDS rotation\", \"CMK\", \"customer managed key\", \"KMS key policy\", \"KMS grant\", \"envelope encryption AWS\", \"AWSCURRENT\".
- 4 stars
- 0 votes
- 0 copies
- 0 views
- Added September 24, 2026
Works with
Security analysis
100/100Pro scans all 2 files and shows the line behind each finding
npx -y skills add chrishuffman5/domain-expert --skill aws-secrets --agent claude-codeAre you the author of Aws Secrets?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/chrishuffman5-aws-secrets)---
name: aws-secrets
description: "Expert agent for AWS Secrets Manager and AWS KMS. Covers secret rotation (Lambda, native RDS), multi-region replication, resource policies, versioning (AWSCURRENT/AWSPREVIOUS), KMS key hierarchy, CMK, grants, key policies, envelope encryption, and multi-region keys. WHEN: \"AWS Secrets Manager\", \"AWS KMS\", \"secret rotation\", \"RDS rotation\", \"CMK\", \"customer managed key\", \"KMS key policy\", \"KMS grant\", \"envelope encryption AWS\", \"AWSCURRENT\"."
license: MIT
---
# AWS Secrets Manager + KMS
This skill covers AWS Secrets Manager and AWS Key Management Service (KMS). It has deep knowledge of secret lifecycle management, automated rotation, KMS key types and hierarchy, IAM integration, and multi-region patterns.
## How to Approach Tasks
When you receive a request:
1. **Classify** the request:
- **Secret CRUD** — Apply Secrets Manager guidance
- **Rotation** — Apply rotation guidance (native vs. Lambda-based)
- **Encryption** — Apply KMS guidance (key types, operations, policies)
- **Cross-account / cross-region** — Apply replication and resource policy guidance
- **IAM integration** — Apply key policy and IAM policy interaction guidance
- **Architecture** — Load `references/architecture.md`
2. **Identify service boundary** — Secrets Manager vs. SSM Parameter Store vs. KMS. Parameter Store is often an adequate alternative for non-rotating, low-sensitivity config.
3. **Provide specific guidance** — Include AWS CLI commands, IAM policy JSON, and Terraform/CDK examples.
## AWS Secrets Manager
### Core Concepts
**Secret**: A protected value (or JSON object) with:
- Name and optional description
- Encryption via KMS (default: `aws/secretsmanager`, customer-managed recommended)
- Automatic rotation (optional)
- Resource-based policy (optional)
- Versioning with staging labels
**Versioning model**:
```
Secret: prod/myapp/db-password
Version A: { value: "old-pass" } AWSPREVIOUS
Version B: { value: "new-pass" } AWSCURRENT
Version C: { value: "pending" } AWSPENDING (during rotation)
```
Applications should always retrieve `AWSCURRENT`. During rotation, `AWSPENDING` is set; after successful rotation and client cutover, it becomes `AWSCURRENT` and the old value becomes `AWSPREVIOUS`.
### Creating and Managing Secrets
```bash
# Create a simple string secret
aws secretsmanager create-secret \
--name prod/myapp/api-key \
--description "Production API key for MyApp" \
--secret-string "my-secret-api-key" \
--kms-key-id alias/my-key
# Create a JSON secret (recommended for multiple values)
aws secretsmanager create-secret \
--name prod/myapp/db-creds \
--secret-string '{"username":"app_user","password":"s3cr3t","host":"db.example.com","port":"5432"}'
# Retrieve current version
aws secretsmanager get-secret-value --secret-id prod/myapp/db-creds
# Retrieve specific version
aws secretsmanager get-secret-value \
--secret-id prod/myapp/db-creds \
--version-stage AWSPREVIOUS
# Update a secret (creates new version, moves AWSCURRENT label)
aws secretsmanager put-secret-value \
--secret-id prod/myapp/api-key \
--secret-string "new-api-key-value"
# Add tags
aws secretsmanager tag-resource \
--secret-id prod/myapp/api-key \
--tags Key=Environment,Value=prod Key=Team,Value=platform
```
### Automatic Rotation
#### Native Rotation (RDS, Redshift, DocumentDB)
For supported database services, enable single-click rotation:
```bash
# Enable rotation for RDS (native, no Lambda needed for supported engines)
aws secretsmanager rotate-secret \
--secret-id prod/myapp/rds-creds \
--rotation-rules AutomaticallyAfterDays=30
# For secrets linked to RDS (using master user secret for rotation)
aws secretsmanager rotate-secret \
--secret-id prod/myapp/rds-creds \
--rotation-lambda-arn arn:aws:lambda:us-east-1:123456789:function:SecretsManagerRDSPostgreSQLRotation \
--rotation-rules AutomaticallyAfterDays=30
```
#### Lambda-Based Rotation
Custom rotation for non-RDS secrets:
```python
# Lambda handler structure (Python)
import boto3
def lambda_handler(event, context):
arn = event['SecretId']
token = event['ClientRequestToken']
step = event['Step']
client = boto3.client('secretsmanager')
if step == 'createSecret':
create_secret(client, arn, token)
elif step == 'setSecret':
set_secret(client, arn, token)
elif step == 'testSecret':
test_secret(client, arn, token)
elif step == 'finishSecret':
finish_secret(client, arn, token)
def create_secret(client, arn, token):
# Generate new secret value and store as AWSPENDING
new_password = generate_password()
client.put_secret_value(
SecretId=arn,
ClientRequestToken=token,
SecretString=new_password,
VersionStages=['AWSPENDING']
)
def set_secret(client, arn, token):
# Apply new secret to the target service (e.g., update DB password)
pending = client.get_secret_value(SecretId=arn, VersionStage='AWSPENDING')
# ... update the database or service
def test_secret(client, arn, token):
# Validate the new secret works
pending = client.get_secret_value(SecretId=arn, VersionStage='AWSPENDING')
# ... test connectivity with new credentials
def finish_secret(client, arn, token):
# Move AWSPENDING to AWSCURRENT
current = client.describe_secret(SecretId=arn)
current_version = [v for v, stages in current['VersionIdsToStages'].items()
if 'AWSCURRENT' in stages][0]
client.update_secret_version_stage(
SecretId=arn,
VersionStage='AWSCURRENT',
MoveToVersionId=token,
RemoveFromVersionId=current_version
)
```
#### Lambda Rotation Function Resource Policy
The Lambda must allow Secrets Manager to invoke it:
```json
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Service": "secretsmanager.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"FunctionName": "arn:aws:lambda:us-east-1:123456789:function:my-rotation-fn",
"Condition": {
"StringEquals": {
"AWS:SourceAccount": "123456789"
}
}
}]
}
```
### Multi-Region Replication
Secrets Manager can replicate secrets to other regions:
```bash
# Replicate secret to additional regions
aws secretsmanager replicate-secret-to-regions \
--secret-id prod/myapp/db-creds \
--add-replica-regions Region=eu-west-1 Region=ap-southeast-1
# List replicas
aws secretsmanager describe-secret --secret-id prod/myapp/db-creds \
--query 'ReplicationStatus'
# Stop replication (and optionally delete replica)
aws secretsmanager remove-regions-from-replication \
--secret-id prod/myapp/db-creds \
--remove-replica-regions eu-west-1
```
**Important**: Each replica uses the default KMS key in that region or a specified CMK. Cross-region CMK replication must be configured separately via KMS multi-region keys.
### Resource-Based Policies
Allow cross-account access to a secret:
```json
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "AllowCrossAccountAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::987654321:role/app-role"
},
"Action": [
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret"
],
"Resource": "*"
}]
}
```
```bash
aws secretsmanager put-resource-policy \
--secret-id prod/myapp/db-creds \
--resource-policy file://policy.json
```
### ABAC with Tags
Use tags for attribute-based access control:
```json
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "*",
"Condition": {
"StringEquals": {
"secretsmanager:ResourceTag/Team": "${aws:PrincipalTag/Team}"
}
}
}]
}
```
---
## AWS KMS
### Key Types
| Type | Algorithm | Use Case |
|---|---|---|
| Symmetric (default) | AES-256-GCM | Envelope encryption, data encryption, SM, S3, EBS, RDS |
| RSA 2048/3072/4096 | RSA-OAEP, RSASSA-PSS, RSASSA-PKCS1-v1_5 | Asymmetric encrypt/decrypt, signing |
| ECC P-256/P-384/P-521/K-256 | ECDSA | Digital signing (code, documents) |
| HMAC (224/256/384/512) | HMAC-SHA2 | Verifiable message authentication |
### Key Categories
**AWS managed keys**: Created by AWS services on your behalf (e.g., `aws/secretsmanager`, `aws/s3`). No charge per key; per-request charges apply. You cannot manage key policy directly.
**Customer managed keys (CMK)**: You create and control. Full key policy control, rotation control, grants. $1/month/key + $0.03/10,000 requests.
**AWS owned keys**: Used internally by AWS services; you cannot see or control them.
### Key Policies
Every KMS key has a resource-based policy. The default key policy grants the AWS account full access (enabling IAM policies to work):
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Enable IAM policies",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::123456789:root"},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow key administrators",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::123456789:role/KeyAdminRole"},
"Action": [
"kms:Create*", "kms:Describe*", "kms:Enable*",
"kms:List*", "kms:Put*", "kms:Update*",
"kms:Revoke*", "kms:Disable*", "kms:Get*",
"kms:Delete*", "kms:ScheduleKeyDeletion", "kms:CancelKeyDeletion"
],
"Resource": "*"
},
{
"Sid": "Allow key usage for services",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::123456789:role/AppRole"},
"Action": ["kms:GenerateDataKey", "kms:Decrypt"],
"Resource": "*"
}
]
}
```
### Key Operations
```bash
# Create a symmetric CMK
aws kms create-key \
--description "Production secrets encryption key" \
--key-usage ENCRYPT_DECRYPT \
--key-spec SYMMETRIC_DEFAULT \
--tags TagKey=Environment,TagValue=prod
# Create an alias
aws kms create-alias \
--alias-name alias/prod-secrets \
--target-key-id <key-id>
# Envelope encryption: generate data key
aws kms generate-data-key \
--key-id alias/prod-secrets \
--key-spec AES_256
# Returns: Plaintext (use immediately), CiphertextBlob (store with data)
# Decrypt data key (when reading encrypted data)
aws kms decrypt \
--ciphertext-blob fileb://encrypted-dek.bin \
--key-id alias/prod-secrets \
--output text --query Plaintext | base64 --decode > dek.bin
# Direct encrypt/decrypt (small payloads only, < 4KB)
aws kms encrypt \
--key-id alias/prod-secrets \
--plaintext "my-secret" \
--output text --query CiphertextBlob
aws kms decrypt \
--ciphertext-blob fileb://ciphertext.bin \
--output text --query Plaintext | base64 --decode
```
### Key Rotation
**Automatic rotation**: Enabled for CMKs; rotates annually (365 days) by default:
```bash
aws kms enable-key-rotation --key-id alias/prod-secrets
# Check rotation status
aws kms get-key-rotation-status --key-id alias/prod-secrets
# On-demand rotation (custom schedule or immediate rotation)
aws kms rotate-key-on-demand --key-id alias/prod-secrets
```
**Rotation behavior**: KMS keeps all previous key material for decryption. The backing key material changes; the key ID, ARN, and alias do not change. Existing ciphertexts remain decryptable.
### KMS Grants
Grants delegate specific key operations to a principal without modifying the key policy:
```bash
# Create a grant allowing a Lambda to use the key
aws kms create-grant \
--key-id alias/prod-secrets \
--grantee-principal arn:aws:iam::123456789:role/rotation-lambda-role \
--operations GenerateDataKey Decrypt \
--name "rotation-lambda-grant"
# List grants
aws kms list-grants --key-id alias/prod-secrets
# Retire a grant (by the grantee)
aws kms retire-grant --grant-token <token>
# Revoke a grant (by key admin)
aws kms revoke-grant --key-id alias/prod-secrets --grant-id <grant-id>
```
**Use grants when**: You need temporary or delegation access without modifying the key policy. Grants are ideal for: automated processes, cross-account key usage, Secrets Manager rotation Lambda.
### Multi-Region Keys
Replicate key material across regions for cross-region decryption (same key ID prefix, different ARN suffix):
```bash
# Create multi-region primary key
aws kms create-key \
--description "Multi-region primary key" \
--multi-region true
# Replicate to another region
aws kms replicate-key \
--key-id arn:aws:kms:us-east-1:123456789:key/mrk-abc123 \
--replica-region eu-west-1
# Multi-region keys have key ID starting with "mrk-"
# Primary: arn:aws:kms:us-east-1:123456789:key/mrk-abc123
# Replica: arn:aws:kms:eu-west-1:123456789:key/mrk-abc123
```
Use multi-region keys with Secrets Manager multi-region replication so replicas can be decrypted in the target region without calling back to the primary region's KMS.
---
## Secrets Manager vs. Parameter Store
| Feature | Secrets Manager | SSM Parameter Store |
|---|---|---|
| Cost | $0.40/secret/month + $0.05/10k API | Free (Standard), $0.05/10k API (Advanced) |
| Automatic rotation | Yes (native + Lambda) | No (manual or custom Lambda) |
| Cross-region replication | Yes (native) | No (manual copy) |
| Secret size | 65,536 bytes | 4KB (Standard), 8KB (Advanced) |
| Resource policies | Yes | No |
| Use when | Database creds, API keys needing rotation | Config values, feature flags, ARNs |
| Encryption | KMS (mandatory) | KMS (SecureString), plaintext option |
For pure configuration that does not require rotation, SSM Parameter Store is more cost-effective. For credentials and secrets requiring lifecycle management, Secrets Manager is appropriate.
## Reference Files
- `references/architecture.md` — SM rotation Lambda internals (4-step contract), versioning mechanics, replication architecture, KMS key hierarchy, grants vs. key policies, envelope encryption implementation, multi-region key architecture.
Files in this skill
- SKILL.md
- references/architecture.md
Attribution
Comments
Loading comments…