AWS Security ChangesHomeSearch

AWS pcs medium security documentation change

Service: pcs · 2025-10-25 · Security-related medium

File: pcs/latest/userguide/multi-cluster-login-script-code.md

Summary

Refactored script to use functions, added AWS Secrets Manager integration for auth key retrieval, improved IMDSv2 handling with IPv6 support, and restructured error handling

Security assessment

Added secure retrieval of authentication keys via AWS Secrets Manager instead of manual input, implemented IMDSv2 token usage with timeouts, and added IPv6 metadata endpoint support. These changes improve security by reducing exposure of credentials and hardening metadata service access.

Diff

diff --git a/pcs/latest/userguide/multi-cluster-login-script-code.md b/pcs/latest/userguide/multi-cluster-login-script-code.md
index fc015fa61..734fe0bb5 100644
--- a//pcs/latest/userguide/multi-cluster-login-script-code.md
+++ b//pcs/latest/userguide/multi-cluster-login-script-code.md
@@ -37 +37 @@ Save the following source code to a file with the following name:
-        echo "Usage: $0 --cluster-identifier <cluster-identifier> [--endpoint-url <endpoint-url>]"
+        echo "Usage: $0 --cluster-identifier <cluster-identifier> [--endpoint-url <endpoint-url>]"
@@ -52,2 +52,2 @@ Save the following source code to a file with the following name:
-        echo "  --cluster-identifier &lt;id&gt;    AWS PCS cluster identifier (required)"
-        echo "  --endpoint-url &lt;url&gt;         Custom PCS endpoint URL (optional)"
+        echo "  --cluster-identifier <id>    AWS PCS cluster identifier (required)"
+        echo "  --endpoint-url <url>         Custom PCS endpoint URL (optional)"
@@ -61,0 +62,26 @@ Save the following source code to a file with the following name:
+    # Function to retrieve authentication key
+    get_auth_key() {
+        if [ "$ALTERNATE_SECRET_RETRIEVAL" = "true" ]; then
+            echo "Retrieving authentication key from AWS Secrets Manager..." >&2
+            local auth_key_arn=$(echo "$CLUSTER_INFO" | jq -r '.cluster.slurmConfiguration.authKey.secretArn')
+            local auth_key_version=$(echo "$CLUSTER_INFO" | jq -r '.cluster.slurmConfiguration.authKey.secretVersion')
+            
+            if [ "$auth_key_arn" = "null" ] || [ "$auth_key_version" = "null" ]; then
+                echo "Error: Auth key information not found in cluster configuration" >&2
+                exit 1
+            fi
+            
+            if ! aws secretsmanager get-secret-value --secret-id "$auth_key_arn" --version-id "$auth_key_version" --query SecretString --output text --region "$REGION" 2>/dev/null; then
+                echo "Error: Failed to retrieve auth key from Secrets Manager" >&2
+                exit 1
+            fi
+        else
+            echo "Please enter the base64-encoded Slurm authentication key:" >&2
+            echo -n "Base64 of the Slurm secret key: " >&2
+            local key
+            read -rs key
+            echo >&2
+            echo "$key"
+        fi
+    }
+    
@@ -71,2 +97,2 @@ Save the following source code to a file with the following name:
-        done &lt; &lt;(find /etc/sysconfig -name "sackd-pcs-*" ! -path "$exclude_file" \
-                 -exec grep SACKD_PORT= '{}' ';' 2&gt;/dev/null | \
+        done < <(find /etc/sysconfig -name "sackd-pcs-*" ! -path "$exclude_file" \
+                 -exec grep SACKD_PORT= '{}' ';' 2>/dev/null | \
@@ -84 +110 @@ Save the following source code to a file with the following name:
-        export SACKD_PORT=$port
+        echo "$port"
@@ -87,116 +113,2 @@ Save the following source code to a file with the following name:
-    # Exit if being sourced for testing
-    [[ "${BASH_SOURCE[0]}" != "${0}" ]] &amp;&amp; return
-    
-    # Parse arguments
-    CLUSTER_IDENTIFIER=""
-    PCS_ENDPOINT_URL=""
-    
-    while [ "$1" != "" ]; do
-        case $1 in
-            --cluster-identifier)
-                shift
-                CLUSTER_IDENTIFIER="$1"
-                ;;
-    
-            --endpoint-url)
-                shift
-                PCS_ENDPOINT_URL="--endpoint-url $1"
-                ;;
-            -h|--help)
-                help
-                exit 0
-                ;;
-            *)
-                echo "Invalid argument: $1" &gt;&amp;2
-                usage &gt;&amp;2
-                exit 1
-                ;;
-        esac
-        shift
-    done
-    
-    # Validate required arguments
-    if [ -z "$CLUSTER_IDENTIFIER" ]; then
-        echo "Error: --cluster-identifier is required" &gt;&amp;2
-        usage &gt;&amp;2
-        exit 1
-    fi
-    
-    # Validate running as root
-    if [ "$EUID" -ne 0 ]; then
-        echo "Error: This script must be run as root" &gt;&amp;2
-        exit 1
-    fi
-    
-    # Validate required commands are available
-    for cmd in aws jq curl; do
-        if ! command -v "$cmd" &amp;&gt; /dev/null; then
-            echo "Error: Required command '$cmd' not found" &gt;&amp;2
-            exit 1
-        fi
-    done
-    
-    # Get the region name from IMDS v2 with error handling
-    echo "Retrieving AWS region from instance metadata..."
-    if ! TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" --max-time 5); then
-        echo "Error: Failed to retrieve IMDS token. Ensure this script is running on an EC2 instance." &gt;&amp;2
-        exit 1
-    fi
-    
-    if ! REGION=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/dynamic/instance-identity/document --max-time 5 | jq -r '.region'); then
-        echo "Error: Failed to retrieve AWS region from instance metadata" &gt;&amp;2
-        exit 1
-    fi
-    
-    echo "Detected AWS region: $REGION"
-    
-    # Retrieve cluster information from AWS PCS
-    echo "Retrieving cluster information for: $CLUSTER_IDENTIFIER"
-    # shellcheck disable=SC2086
-    if ! CLUSTER_INFO=$(aws pcs get-cluster --region "$REGION" --cluster-identifier "$CLUSTER_IDENTIFIER" $PCS_ENDPOINT_URL 2&gt;/dev/null); then
-        echo "Error: Failed to retrieve cluster information. Check cluster identifier and AWS permissions." &gt;&amp;2
-        exit 1
-    fi
-    
-    CLUSTER_ID=$(echo "$CLUSTER_INFO" | jq -r '.cluster.id')
-    CLUSTER_NAME="$(echo "$CLUSTER_INFO" | jq -r '.cluster.name')"
-    SLURM_VERSION=$(echo "$CLUSTER_INFO" | jq -r '.cluster.scheduler.version')
-    SLURM_VERSION=${SLURM_VERSION#Slurm_}
-    
-    # Check if Slurm version is &gt;= 25.05
-    # shellcheck disable=SC2072
-    if [[ "$SLURM_VERSION" &lt; "25.05" ]]; then
-        echo "Error: This script requires Slurm version 25.05 or later. Found version: $SLURM_VERSION" &gt;&amp;2
-        exit 1
-    fi
-    
-    ENDPOINTS=$(echo "$CLUSTER_INFO" | jq -r '.cluster.endpoints[] | select(.type == "SLURMCTLD") | "\(.privateIpAddress):\(.port)"' | tr '\n' ',' | sed 's/,$//')
-    
-    # Get BASE64_SLURM_KEY based on ALTERNATE_SECRET_RETRIEVAL setting
-    if [ "$ALTERNATE_SECRET_RETRIEVAL" = "true" ]; then
-        echo "Retrieving authentication key from AWS Secrets Manager..."
-        AUTH_KEY_ARN=$(echo "$CLUSTER_INFO" | jq -r '.cluster.slurmConfiguration.authKey.secretArn')
-        AUTH_KEY_VERSION=$(echo "$CLUSTER_INFO" | jq -r '.cluster.slurmConfiguration.authKey.secretVersion')
-        
-        if [ "$AUTH_KEY_ARN" = "null" ] || [ "$AUTH_KEY_VERSION" = "null" ]; then
-            echo "Error: Auth key information not found in cluster configuration" &gt;&amp;2
-            exit 1
-        fi
-        
-        if ! BASE64_SLURM_KEY="$(aws secretsmanager get-secret-value --secret-id "$AUTH_KEY_ARN" --version-id "$AUTH_KEY_VERSION" --query SecretString --output text --region "$REGION" 2&gt;/dev/null)"; then
-            echo "Error: Failed to retrieve auth key from Secrets Manager" &gt;&amp;2
-            exit 1
-        fi
-    else
-        # Prompt for base64 Slurm key interactively
-        echo "Please enter the base64-encoded Slurm authentication key:"
-        echo -n "Base64 of the Slurm secret key: "
-        read -rs BASE64_SLURM_KEY
-        echo
-    fi
-    
-    if [ -z "$BASE64_SLURM_KEY" ]; then
-        echo "Error: base64 Slurm key cannot be empty" &gt;&amp;2
-        exit 1
-    fi
-    
+    # Function to configure cluster
+    configure_cluster() {
@@ -205 +117 @@ Save the following source code to a file with the following name:
-    echo '{"keys":[{"alg":"HS256","kty":"oct","kid":"key-'"${CLUSTER_ID}"'","k":"'"${BASE64_SLURM_KEY}"'"}]}' | jq -c '.' &gt; "${SLURM_JWKS_FILE}"
+        echo '{"keys":[{"alg":"HS256","kty":"oct","kid":"key-'"${CLUSTER_ID}"'","k":"'"${BASE64_SLURM_KEY}"'"}]}' | jq -c '.' > "${SLURM_JWKS_FILE}"
@@ -216 +127,0 @@ Save the following source code to a file with the following name:
-    # Configure sackd to connect to the AWS PCS cluster (using dynamic version)
@@ -220,2 +131,2 @@ Save the following source code to a file with the following name:
-    get_next_sackd_port "$SACKD_SERVICE_ENV"
-    cat &gt; "${SACKD_SERVICE_ENV}" &lt;&lt; EOF
+        SACKD_PORT=$(get_next_sackd_port "$SACKD_SERVICE_ENV")
+        cat > "${SACKD_SERVICE_ENV}" << EOF
@@ -230 +141 @@ Save the following source code to a file with the following name:
-    cat &lt;&lt; EOF &gt; "$SACKD_SERVICE_PATH"
+        cat << EOF > "$SACKD_SERVICE_PATH"
@@ -257 +168 @@ Save the following source code to a file with the following name:
-    systemctl daemon-reload &amp;&amp; systemctl enable "$SACKD_SERVICE_NAME"
+        systemctl daemon-reload && systemctl enable "$SACKD_SERVICE_NAME"
@@ -260 +170,0 @@ Save the following source code to a file with the following name:
-    # Create activate script
@@ -262 +172 @@ Save the following source code to a file with the following name:
-    cat &gt; "$ACTIVATE_SCRIPT" &lt;&lt; EOF
+        cat > "$ACTIVATE_SCRIPT" << EOF
@@ -295,0 +206,103 @@ Save the following source code to a file with the following name:
+    }
+    
+    # Main function
+    main() {
+        # Parse arguments
+        CLUSTER_IDENTIFIER=""
+        PCS_ENDPOINT_URL=""
+        
+        while [ "$1" != "" ]; do
+            case $1 in
+                --cluster-identifier)
+                    shift