AWS code-library medium security documentation change
Summary
Updated Amazon Connect setup script to include security best practices: restricted log file permissions, AWS CLI/credentials validation, secure random generation fallbacks, improved error handling, and auto-cleanup.
Security assessment
The change adds concrete security improvements: setting log file permissions to 600 prevents unauthorized access to sensitive logs; secure password generation fallback ensures cryptographic randomness even if primary tool fails; and AWS credentials validation prevents accidental execution with invalid credentials. These changes mitigate potential information disclosure and unauthorized access risks.
Diff
diff --git a/code-library/latest/ug/connect_example_connect_GettingStarted_027_section.md b/code-library/latest/ug/connect_example_connect_GettingStarted_027_section.md index c3cf12b27..3c39b7910 100644 --- a//code-library/latest/ug/connect_example_connect_GettingStarted_027_section.md +++ b//code-library/latest/ug/connect_example_connect_GettingStarted_027_section.md @@ -42 +42,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - # Set up logging + set -euo pipefail + + # Set up logging with restricted permissions @@ -43,0 +46,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru + touch "$LOG_FILE" + chmod 600 "$LOG_FILE" @@ -47 +51 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - AWS_REGION="us-west-2" + AWS_REGION="${AWS_REGION:-us-west-2}" @@ -49,0 +54,11 @@ There's more on GitHub. Find the complete example and learn how to set up and ru + # Validate AWS CLI is installed and credentials are available + if ! command -v aws &> /dev/null; then + echo "ERROR: AWS CLI is not installed" | tee -a "$LOG_FILE" + exit 1 + fi + + if ! aws sts get-caller-identity &> /dev/null; then + echo "ERROR: AWS credentials are not configured or invalid" | tee -a "$LOG_FILE" + exit 1 + fi + @@ -52,2 +67,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo "$(date): Running command: $1" >> "$LOG_FILE" - eval "$1" 2>&1 | tee -a "$LOG_FILE" + local cmd="$1" + echo "$(date): Running command: $cmd" >> "$LOG_FILE" + eval "$cmd" 2>&1 | tee -a "$LOG_FILE" @@ -74 +90 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - if [[ -n "$INSTANCE_ID" ]]; then + if [[ -n "${INSTANCE_ID:-}" ]]; then @@ -76 +92 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - log_cmd "aws connect delete-instance --instance-id $INSTANCE_ID --region $AWS_REGION" + log_cmd "aws connect delete-instance --instance-id '$INSTANCE_ID' --region '$AWS_REGION'" || true @@ -81,0 +98,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru + # Set trap to clean up on error + trap cleanup_on_error ERR EXIT + @@ -94 +113,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - local result=$(log_cmd "aws connect describe-instance --instance-id $instance_id --region $AWS_REGION --output json") + local result + result=$(log_cmd "aws connect describe-instance --instance-id '$instance_id' --region '$AWS_REGION' --output json" 2>&1) || true @@ -115 +135,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - local instances=$(log_cmd "aws connect list-instances --region $AWS_REGION --output json") + local instances + instances=$(log_cmd "aws connect list-instances --region '$AWS_REGION' --output json" 2>&1) || true @@ -122 +143,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - local instance_count=$(echo "$instances" | grep -o '"Id":' | wc -l) + local instance_count + instance_count=$(echo "$instances" | jq '.InstanceSummaryList | length' 2>/dev/null || echo 0) @@ -126 +148 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo "$instances" | grep -A 1 '"Id":' | tee -a "$LOG_FILE" + echo "$instances" | jq '.InstanceSummaryList[] | {Id, Alias}' 2>/dev/null | tee -a "$LOG_FILE" || true @@ -133,2 +155 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo "Do you want to delete these instances to free up quota? (y/n): " - read -r DELETE_CHOICE + echo "Auto-deleting existing instances to free up quota..." | tee -a "$LOG_FILE" @@ -136 +156,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - if [[ "$DELETE_CHOICE" =~ ^[Yy] ]]; then @@ -140 +160,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - local instance_ids=($(echo "$instances" | grep -o '"Id": "[^"]*' | cut -d'"' -f4)) + local instance_ids + instance_ids=$(echo "$instances" | jq -r '.InstanceSummaryList[].Id' 2>/dev/null || echo "") @@ -142 +163,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - for id in "${instance_ids[@]}"; do + while IFS= read -r id; do + if [[ -n "$id" ]]; then @@ -144,3 +166 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - log_cmd "aws connect delete-instance --instance-id $id --region $AWS_REGION" - - if [[ $? -ne 0 ]]; then + log_cmd "aws connect delete-instance --instance-id '$id' --region '$AWS_REGION'" || { @@ -148,3 +168 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - else - echo "Successfully deleted instance $id" | tee -a "$LOG_FILE" - fi + } @@ -154 +172,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - done + fi + done <<< "$instance_ids" @@ -158,3 +176,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - else - echo "Keeping existing instances. Script may fail if quota is reached." | tee -a "$LOG_FILE" - fi @@ -172 +188 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - INSTANCE_ALIAS="connect-instance-$(openssl rand -hex 6)" + INSTANCE_ALIAS="connect-instance-$(openssl rand -hex 6 2>/dev/null || date +%s%N)" @@ -177 +193 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - INSTANCE_RESULT=$(log_cmd "aws connect create-instance --identity-management-type CONNECT_MANAGED --instance-alias $INSTANCE_ALIAS --inbound-calls-enabled --outbound-calls-enabled --region $AWS_REGION --output json") + INSTANCE_RESULT=$(log_cmd "aws connect create-instance --identity-management-type CONNECT_MANAGED --instance-alias '$INSTANCE_ALIAS' --inbound-calls-enabled --outbound-calls-enabled --region '$AWS_REGION' --output json" 2>&1) || true @@ -184 +199,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - cleanup_on_error @@ -188,3 +203,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - # Extract instance ID from the result - INSTANCE_ID=$(echo "$INSTANCE_RESULT" | grep -o '"Id": "[^"]*' | cut -d'"' -f4) - INSTANCE_ARN=$(echo "$INSTANCE_RESULT" | grep -o '"Arn": "[^"]*' | cut -d'"' -f4) + # Extract instance ID from the result using jq + INSTANCE_ID=$(echo "$INSTANCE_RESULT" | jq -r '.InstanceId' 2>/dev/null || echo "") + INSTANCE_ARN=$(echo "$INSTANCE_RESULT" | jq -r '.InstanceArn' 2>/dev/null || echo "") @@ -203 +217,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - cleanup_on_error @@ -209 +223 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - SECURITY_PROFILES=$(log_cmd "aws connect list-security-profiles --instance-id $INSTANCE_ID --region $AWS_REGION --output json") + SECURITY_PROFILES=$(log_cmd "aws connect list-security-profiles --instance-id '$INSTANCE_ID' --region '$AWS_REGION' --output json" 2>&1) || true @@ -212 +225,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - cleanup_on_error @@ -216,16 +229,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - # Save security profiles to a temporary file for easier processing - TEMP_FILE=$(mktemp) - echo "$SECURITY_PROFILES" > "$TEMP_FILE" - - # Extract Admin security profile ID using grep and awk - ADMIN_PROFILE_ID="" - while IFS= read -r line; do - if [[ "$line" =~ \"Name\":\ \"Admin\" ]]; then - # Found the Admin profile, now get the ID from previous lines - ADMIN_PROFILE_ID=$(grep -B 2 "$line" "$TEMP_FILE" | grep -o '"Id": "[^"]*' | head -1 | cut -d'"' -f4) - break - fi - done < "$TEMP_FILE" - - # Clean up - rm -f "$TEMP_FILE" + # Extract Admin security profile ID using jq + ADMIN_PROFILE_ID=$(echo "$SECURITY_PROFILES" | jq -r '.SecurityProfileSummaryList[] | select(.Name=="Admin") | .Id' 2>/dev/null | head -1 || echo "") @@ -236,2 +235 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo "$SECURITY_PROFILES" | tee -a "$LOG_FILE" - cleanup_on_error + echo "$SECURITY_PROFILES" | jq '.SecurityProfileSummaryList[] | {Id, Name}' 2>/dev/null | tee -a "$LOG_FILE" || echo "$SECURITY_PROFILES" | tee -a "$LOG_FILE" @@ -245 +243 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - ROUTING_PROFILES=$(log_cmd "aws connect list-routing-profiles --instance-id $INSTANCE_ID --region $AWS_REGION --output json") + ROUTING_PROFILES=$(log_cmd "aws connect list-routing-profiles --instance-id '$INSTANCE_ID' --region '$AWS_REGION' --output json" 2>&1) || true @@ -248 +245,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - cleanup_on_error @@ -252,2 +249,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - # Extract the first routing profile ID - ROUTING_PROFILE_ID=$(echo "$ROUTING_PROFILES" | grep -o '"Id": "[^"]*' | head -1 | cut -d'"' -f4) + # Extract the first routing profile ID using jq + ROUTING_PROFILE_ID=$(echo "$ROUTING_PROFILES" | jq -r '.RoutingProfileSummaryList[0].Id' 2>/dev/null || echo "") @@ -257 +253,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - cleanup_on_error @@ -267 +263 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - ADMIN_PASSWORD="Connect$(openssl rand -base64 12)" + ADMIN_PASSWORD="Connect$(openssl rand -base64 12 2>/dev/null || head -c 12 /dev/urandom | base64)" @@ -269 +265 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - USER_RESULT=$(log_cmd "aws connect create-user --instance-id $INSTANCE_ID --username admin --password \"$ADMIN_PASSWORD\" --identity-info FirstName=Admin,LastName=User,[email protected] --phone-config PhoneType=DESK_PHONE,AutoAccept=true,AfterContactWorkTimeLimit=30,DeskPhoneNumber=+12065550100 --security-profile-ids $ADMIN_PROFILE_ID --routing-profile-id $ROUTING_PROFILE_ID --region $AWS_REGION --output json") + USER_RESULT=$(log_cmd "aws connect create-user --instance-id '$INSTANCE_ID' --username admin --password '$ADMIN_PASSWORD' --identity-info FirstName=Admin,LastName=User,[email protected] --phone-config PhoneType=DESK_PHONE,AutoAccept=true,AfterContactWorkTimeLimit=30,DeskPhoneNumber=+12065550100 --security-profile-ids '$ADMIN_PROFILE_ID' --routing-profile-id '$ROUTING_PROFILE_ID' --region '$AWS_REGION' --output json" 2>&1) || true @@ -272 +267,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - cleanup_on_error @@ -276,2 +271,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - # Extract user ID - USER_ID=$(echo "$USER_RESULT" | grep -o '"UserId": "[^"]*\|"Id": "[^"]*' | head -1 | cut -d'"' -f4) + # Extract user ID using jq + USER_ID=$(echo "$USER_RESULT" | jq -r '.UserId' 2>/dev/null || echo "") @@ -281 +275,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - cleanup_on_error @@ -286,0 +281 @@ There's more on GitHub. Find the complete example and learn how to set up and ru + chmod 600 "$LOG_FILE" @@ -292 +287 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - EARLY_MEDIA_RESULT=$(log_cmd "aws connect update-instance-attribute --instance-id $INSTANCE_ID --attribute-type EARLY_MEDIA --value true --region $AWS_REGION") + EARLY_MEDIA_RESULT=$(log_cmd "aws connect update-instance-attribute --instance-id '$INSTANCE_ID' --attribute-type EARLY_MEDIA --value true --region '$AWS_REGION'" 2>&1) || true @@ -295 +289,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - cleanup_on_error @@ -300 +294 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - MULTI_PARTY_RESULT=$(log_cmd "aws connect update-instance-attribute --instance-id $INSTANCE_ID --attribute-type MULTI_PARTY_CONFERENCE --value true --region $AWS_REGION") + MULTI_PARTY_RESULT=$(log_cmd "aws connect update-instance-attribute --instance-id '$INSTANCE_ID' --attribute-type MULTI_PARTY_CONFERENCE --value true --region '$AWS_REGION'" 2>&1) || true @@ -303 +296,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - cleanup_on_error @@ -308 +301 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - MULTI_PARTY_CHAT_RESULT=$(log_cmd "aws connect update-instance-attribute --instance-id $INSTANCE_ID --attribute-type MULTI_PARTY_CHAT_CONFERENCE --value true --region $AWS_REGION") + MULTI_PARTY_CHAT_RESULT=$(log_cmd "aws connect update-instance-attribute --instance-id '$INSTANCE_ID' --attribute-type MULTI_PARTY_CHAT_CONFERENCE --value true --region '$AWS_REGION'" 2>&1) || true @@ -311 +303,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - cleanup_on_error @@ -321 +313 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - STORAGE_CONFIGS=$(log_cmd "aws connect list-instance-storage-configs --instance-id $INSTANCE_ID --resource-type CHAT_TRANSCRIPTS --region $AWS_REGION --output json") + STORAGE_CONFIGS=$(log_cmd "aws connect list-instance-storage-configs --instance-id '$INSTANCE_ID' --resource-type CHAT_TRANSCRIPTS --region '$AWS_REGION' --output json" 2>&1) || true @@ -324 +315,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - cleanup_on_error @@ -332 +323 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - INSTANCE_DETAILS=$(log_cmd "aws connect describe-instance --instance-id $INSTANCE_ID --region $AWS_REGION --output json") + INSTANCE_DETAILS=$(log_cmd "aws connect describe-instance --instance-id '$INSTANCE_ID' --region '$AWS_REGION' --output json" 2>&1) || true @@ -335 +325,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - cleanup_on_error @@ -343 +333 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - PHONE_NUMBERS=$(log_cmd "aws connect search-available-phone-numbers --target-arn $INSTANCE_ARN --phone-number-type TOLL_FREE --phone-number-country-code US --max-results 5 --region $AWS_REGION --output json") + PHONE_NUMBERS=$(log_cmd "aws connect search-available-phone-numbers --target-arn '$INSTANCE_ARN' --phone-number-type TOLL_FREE --phone-number-country-code US --max-results 5 --region '$AWS_REGION' --output json" 2>&1) || true @@ -346 +335,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - cleanup_on_error @@ -350,2 +339,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - # Extract the first phone number if available - PHONE_NUMBER=$(echo "$PHONE_NUMBERS" | grep -o '"PhoneNumber": "[^"]*' | head -1 | cut -d'"' -f4) + # Extract the first phone number if available using jq + PHONE_NUMBER=$(echo "$PHONE_NUMBERS" | jq -r '.AvailableNumbersList[0].PhoneNumber' 2>/dev/null || echo "") @@ -356 +344,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru