AWS IAM documentation change
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"