AWS Security ChangesHomeSearch

AWS IAM documentation change

Service: IAM · 2026-05-01 · Documentation low

File: IAM/latest/UserGuide/sts_example_secrets_manager_GettingStarted_073_section.md

Summary

Updated Secrets Manager tutorial script with security enhancements: improved random ID generation, secure cleanup, least-privilege policies, secret rotation recommendations, and cryptographic secret generation.

Security assessment

Changes focus on security best practices like replacing insecure random ID generation with Python's secrets module, implementing least-privilege resource policies with version stage conditions, adding secret rotation recommendations, and using cryptographic methods for secret generation. No evidence of addressing a specific vulnerability.

Diff

diff --git a/IAM/latest/UserGuide/sts_example_secrets_manager_GettingStarted_073_section.md b/IAM/latest/UserGuide/sts_example_secrets_manager_GettingStarted_073_section.md
index 271d06fe0..66fe4aa15 100644
--- a//IAM/latest/UserGuide/sts_example_secrets_manager_GettingStarted_073_section.md
+++ b//IAM/latest/UserGuide/sts_example_secrets_manager_GettingStarted_073_section.md
@@ -40,0 +41,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    set -euo pipefail
+    
@@ -53 +55 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        if echo "$output" | grep -i "error" > /dev/null; then
+        if echo "$output" | grep -qi "error"; then
@@ -61 +63 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    # Function to generate a random identifier
+    # Function to generate a random identifier using secure method
@@ -63 +65 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        echo "sm$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 8 | head -n 1)"
+        python3 -c "import secrets; print('sm' + secrets.token_hex(4))"
@@ -66 +68 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    # Function to clean up resources
+    # Function to safely clean up resources
@@ -73 +75 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        if [ -n "$SECRET_NAME" ]; then
+        if [ -n "${SECRET_NAME:-}" ]; then
@@ -77 +79 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        if [ -n "$RUNTIME_ROLE_NAME" ]; then
+        if [ -n "${RUNTIME_ROLE_NAME:-}" ]; then
@@ -81 +83 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        if [ -n "$ADMIN_ROLE_NAME" ]; then
+        if [ -n "${ADMIN_ROLE_NAME:-}" ]; then
@@ -89,5 +91 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        echo "Do you want to clean up all created resources? (y/n): "
-        read -r CLEANUP_CHOICE
-        
-        if [[ "$CLEANUP_CHOICE" =~ ^[Yy]$ ]]; then
-            echo "Cleaning up resources..."
+        echo "Cleaning up all created resources..."
@@ -96 +94 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            if [ -n "$SECRET_NAME" ]; then
+        if [ -n "${SECRET_NAME:-}" ]; then
@@ -98 +96 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                aws secretsmanager delete-secret --secret-id "$SECRET_NAME" --force-delete-without-recovery
+            aws secretsmanager delete-secret --secret-id "$SECRET_NAME" --force-delete-without-recovery 2>/dev/null || true
@@ -102 +100,5 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            if [ -n "$RUNTIME_ROLE_NAME" ]; then
+        if [ -n "${RUNTIME_ROLE_NAME:-}" ]; then
+            echo "Deleting inline policies from runtime role: $RUNTIME_ROLE_NAME"
+            for policy in $(aws iam list-role-policies --role-name "$RUNTIME_ROLE_NAME" --query 'PolicyNames[]' --output text 2>/dev/null || true); do
+                aws iam delete-role-policy --role-name "$RUNTIME_ROLE_NAME" --policy-name "$policy" 2>/dev/null || true
+            done
@@ -104 +106 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                aws iam delete-role --role-name "$RUNTIME_ROLE_NAME"
+            aws iam delete-role --role-name "$RUNTIME_ROLE_NAME" 2>/dev/null || true
@@ -108 +110 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            if [ -n "$ADMIN_ROLE_NAME" ]; then
+        if [ -n "${ADMIN_ROLE_NAME:-}" ]; then
@@ -110 +112,5 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                aws iam detach-role-policy --role-name "$ADMIN_ROLE_NAME" --policy-arn "arn:aws:iam::aws:policy/SecretsManagerReadWrite"
+            aws iam detach-role-policy --role-name "$ADMIN_ROLE_NAME" --policy-arn "arn:aws:iam::aws:policy/SecretsManagerReadWrite" 2>/dev/null || true
+            
+            for policy in $(aws iam list-role-policies --role-name "$ADMIN_ROLE_NAME" --query 'PolicyNames[]' --output text 2>/dev/null || true); do
+                aws iam delete-role-policy --role-name "$ADMIN_ROLE_NAME" --policy-name "$policy" 2>/dev/null || true
+            done
@@ -113 +119 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                aws iam delete-role --role-name "$ADMIN_ROLE_NAME"
+            aws iam delete-role --role-name "$ADMIN_ROLE_NAME" 2>/dev/null || true
@@ -117,3 +122,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        else
-            echo "Resources will not be deleted."
-        fi
@@ -123 +126 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    trap 'echo "Script interrupted. Running cleanup..."; cleanup_resources' INT TERM
+    trap 'echo "Script interrupted. Running cleanup..."; cleanup_resources' INT TERM EXIT
@@ -139,5 +142,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    # Create the SecretsManagerAdmin role
-    echo "Creating admin role: $ADMIN_ROLE_NAME"
-    ADMIN_ROLE_OUTPUT=$(aws iam create-role \
-        --role-name "$ADMIN_ROLE_NAME" \
-        --assume-role-policy-document '{
+    # Create assume role policy document
+    ASSUME_ROLE_POLICY=$(cat <<'EOF'
+    {
@@ -154 +155,9 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        }')
+    }
+    EOF
+    )
+    
+    # Create the SecretsManagerAdmin role
+    echo "Creating admin role: $ADMIN_ROLE_NAME"
+    ADMIN_ROLE_OUTPUT=$(aws iam create-role \
+        --role-name "$ADMIN_ROLE_NAME" \
+        --assume-role-policy-document "$ASSUME_ROLE_POLICY" 2>&1)
@@ -163 +172 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        --policy-arn "arn:aws:iam::aws:policy/SecretsManagerReadWrite")
+        --policy-arn "arn:aws:iam::aws:policy/SecretsManagerReadWrite" 2>&1)
@@ -166 +175 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    echo "$ATTACH_POLICY_OUTPUT"
+    echo "Policy attached successfully"
@@ -172,12 +181 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        --assume-role-policy-document '{
-            "Version":"2012-10-17",
-            "Statement": [
-                {
-                    "Effect": "Allow",
-                    "Principal": {
-                        "Service": "ec2.amazonaws.com"
-                    },
-                    "Action": "sts:AssumeRole"
-                }
-            ]
-        }')
+        --assume-role-policy-document "$ASSUME_ROLE_POLICY" 2>&1)
@@ -194,0 +193,8 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    # Generate secure secret value using environment variable or secure method
+    # WARNING: In production, use secure methods to inject secrets (AWS CodeBuild, parameter store, etc.)
+    if [ -z "${TUTORIAL_SECRET_VALUE:-}" ]; then
+        SECRET_VALUE=$(python3 -c "import json; print(json.dumps({'ClientID':'my_client_id','ClientSecret':__import__('secrets').token_urlsafe(32)}))")
+    else
+        SECRET_VALUE="$TUTORIAL_SECRET_VALUE"
+    fi
+    
@@ -198 +204,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        --secret-string '{"ClientID":"my_client_id","ClientSecret":"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}')
+        --secret-string "$SECRET_VALUE" \
+        --add-replica-regions 'Region=us-east-1' 2>&1)
@@ -205,3 +212,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    ACCOUNT_ID_OUTPUT=$(aws sts get-caller-identity --query "Account" --output text)
-    check_error "$ACCOUNT_ID_OUTPUT" "get-caller-identity"
-    ACCOUNT_ID=$ACCOUNT_ID_OUTPUT
+    ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text 2>&1)
+    check_error "$ACCOUNT_ID" "get-caller-identity"
@@ -210 +216,9 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    # Add resource policy to the secret
+    # Get secret ARN for precise resource policy
+    echo "Getting secret ARN..."
+    SECRET_ARN=$(aws secretsmanager describe-secret \
+        --secret-id "$SECRET_NAME" \
+        --query 'ARN' \
+        --output text 2>&1)
+    check_error "$SECRET_ARN" "describe-secret"
+    
+    # Add resource policy to the secret with least privilege
@@ -216,0 +231 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+                "Sid": "AllowRuntimeRoleReadSecret",
@@ -222 +237,6 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                "Resource": "*"
+                "Resource": "$SECRET_ARN",
+                "Condition": {
+                    "StringEquals": {
+                        "secretsmanager:VersionStage": "AWSCURRENT"
+                    }
+                }
@@ -232 +252 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        --block-public-policy)
+        --block-public-policy 2>&1)
@@ -235 +255,7 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    echo "$PUT_POLICY_OUTPUT"
+    echo "Resource policy added successfully"
+    
+    # Enable rotation policy recommendation
+    echo "Enabling secret metadata tags for rotation tracking..."
+    aws secretsmanager tag-resource \
+        --secret-id "$SECRET_NAME" \
+        --tags Key=Purpose,Value=Tutorial Key=AutoRotation,Value=Recommended 2>/dev/null || true
@@ -240 +266 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        --secret-id "$SECRET_NAME")
+        --secret-id "$SECRET_NAME" 2>&1)
@@ -244 +270 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    echo "$GET_SECRET_OUTPUT" | grep -v "SecretString"
+    echo "$GET_SECRET_OUTPUT" | jq '{ARN: .ARN, Name: .Name, LastUpdatedDate: .LastUpdatedDate, VersionIdsToStages: .VersionIdsToStages}' 2>/dev/null || echo "Secret metadata retrieved (jq not available)"
@@ -247,0 +274,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    UPDATE_SECRET_VALUE=$(python3 -c "import json; print(json.dumps({'ClientID':'my_new_client_id','ClientSecret':__import__('secrets').token_urlsafe(32)}))")
+    
@@ -250 +278 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        --secret-string '{"ClientID":"my_new_client_id","ClientSecret":"bPxRfiCYEXAMPLEKEY/wJalrXUtnFEMI/K7MDENG"}')
+        --secret-string "$UPDATE_SECRET_VALUE" 2>&1)
@@ -253 +281 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    echo "$UPDATE_SECRET_OUTPUT"
+    echo "Secret updated successfully"
@@ -258 +286 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        --secret-id "$SECRET_NAME")
+        --secret-id "$SECRET_NAME" 2>&1)
@@ -262 +290,14 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    echo "$VERIFY_SECRET_OUTPUT" | grep -v "SecretString"
+    echo "$VERIFY_SECRET_OUTPUT" | jq '{ARN: .ARN, Name: .Name, LastUpdatedDate: .LastUpdatedDate, VersionIdsToStages: .VersionIdsToStages}' 2>/dev/null || echo "Secret metadata retrieved (jq not available)"
+    
+    # Step 6: Display rotation recommendations
+    echo ""
+    echo "Rotation Configuration Recommendations:"
+    echo "========================================"
+    DESCRIBE_OUTPUT=$(aws secretsmanager describe-secret --secret-id "$SECRET_NAME" 2>&1)
+    if echo "$DESCRIBE_OUTPUT" | grep -q "RotationRules"; then
+        echo "Current rotation configuration:"
+        echo "$DESCRIBE_OUTPUT" | jq '.RotationRules' 2>/dev/null || echo "Rotation rules available"
+    else
+        echo "No automatic rotation configured. Consider enabling rotation with:"
+        echo "aws secretsmanager rotate-secret --secret-id $SECRET_NAME --rotation-lambda-arn arn:aws:lambda:REGION:ACCOUNT:function:FUNCTION_NAME --rotation-rules AutomaticallyAfterDays=30"
+    fi
@@ -270,2 +311,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    echo "2. Created a secret in AWS Secrets Manager"
-    echo "3. Added a resource policy to control access to the secret"