Published: 2026-06-01 • Updated: 2026-06-17

Setting Up the AWS CLI and Developer Tools: Enterprise Installation, Security Hardening, and Automation

A masterclass on configuring, securing, and automating the AWS Command Line Interface (CLI) v2, AWS Session Manager, and modern developer utilities for enterprise-scale operations.


Table of Contents


1. Introduction to Enterprise AWS Developer Tooling

In modern cloud engineering, the web console is a learning aid, not an operational tool. Enterprise DevOps, Platform Engineering, and SysOps Automation require programmatic, reproducible, and highly secure access to the AWS control plane. The core instrument for this access is the AWS Command Line Interface (CLI) v2, supported by developer utilities like the AWS Cloud Development Kit (CDK), AWS Session Manager Plugin, and static analysis tools.

However, setting up these tools in an enterprise environment involves more than running an installation script. It requires architecting a local workstation environment that adheres to the principle of least privilege, integrates with centralized Identity Providers (IdPs) via AWS IAM Identity Center (formerly AWS SSO), prevents credential leakage, and leverages advanced CLI features for high-performance automation.

Featured Snippet Answer: What is the AWS CLI v2 and why is it preferred over v1? The AWS CLI v2 is the current generation of the AWS command-line tool, rewritten to offer native binary delivery, direct integration with AWS IAM Identity Center (SSO), interactive features (like auto-prompting and completions), wizard-driven configurations, and support for modern protocols like WebSockets. Unlike v1, which requires a Python runtime on the host system, AWS CLI v2 compiles all dependencies into a standalone package, eliminating runtime version conflicts and simplifying enterprise distribution.

2. What You Will Learn

This comprehensive guide will teach you how to:

  • Design a secure, multi-account developer environment using AWS CLI v2.
  • Cryptographically verify AWS CLI installations to prevent supply-chain attacks.
  • Configure AWS IAM Identity Center (SSO) for automated, short-lived token management.
  • Master JMESPath queries to filter and format complex JSON payloads directly on the client side.
  • Harden developer workstations against credential theft using tools like AWS Vault.
  • Deploy and utilize the AWS Session Manager plugin for secure, keyless SSH-like access.
  • Write robust, production-grade shell scripts with complex error handling and parallel execution.

3. Prerequisites

To get the most out of this masterclass, you should have:

  • Access to an AWS Account (preferably managed via AWS Organizations with IAM Identity Center enabled).
  • A local workstation running Linux (Ubuntu/RHEL), macOS, or Windows with WSL2 (Windows Subsystem for Linux).
  • Basic familiarity with terminal environments, shell scripting (Bash or Zsh), and JSON structures.

4. Architectural Overview of AWS Developer Tools

To troubleshoot and secure developer tools effectively, you must understand how they communicate with the AWS API. Every command executed via the AWS CLI undergoes a complex cycle of authentication, signing, transport, and evaluation.

The AWS CLI Request Lifecycle

When you execute a command such as aws ec2 describe-instances, the following architectural workflow occurs:

+---------------------------------------------------------------------------------+
|                           Developer Workstation                                 |
|                                                                                 |
|  +------------------+     +--------------------+     +-----------------------+  |
|  | 1. User Command  | --> | 2. Profile Loader  | --> | 3. Credential Provider|  |
|  |  (aws ec2 ...)   |     |  (~/.aws/config)   |     |  (SSO Token / Keys)   |  |
|  +------------------+     +--------------------+     +-----------------------+  |
|                                                                  |              |
|                                                                  v              |
|  +------------------+     +--------------------+     +-----------------------+  |
|  | 6. CLI Output    | <-- | 5. JSON Response   | <-- | 4. SigV4 Signer &     |  |
|  |  (Format/Filter) |     |  (Deserializer)    |     |    HTTPS Client       |  |
|  +------------------+     +--------------------+     +-----------------------+  |
+------------------------------------------------------------------|--------------+
                                                                   |
                                                      HTTPS Port 443 (TLS v1.3)
                                                                   |
                                                                   v
+---------------------------------------------------------------------------------+
|                                 AWS Cloud                                       |
|                                                                                 |
|       +-----------------------+              +-----------------------+          |
|       |  AWS Regional Endpoint| -----------> |  AWS IAM / STS Engine |          |
|       |  (e.g., ec2.aws...)   |              |  (Signature & Policy) |          |
|       +-----------------------+              +-----------------------+          |
|                   |                                      |                      |
|                   v                                      v                      |
|       +-----------------------+              +-----------------------+          |
|       |   Service Control     | <----------- |   Authorization       |          |
|       |   Plane Execution     |              |   Decision (Allow)    |          |
|       +-----------------------+              +-----------------------+          |
+---------------------------------------------------------------------------------+
    

Key Architectural Components

Let's break down the critical components of this architecture:

  • Signature Version 4 (SigV4) Signing: The AWS CLI automatically signs all outgoing HTTP requests using AWS Signature Version 4. This protocol uses cryptographic hashing (SHA-256) to sign the request date, endpoint, headers, and body with your secret access key or temporary session token. This ensures that the request cannot be tampered with in transit (preventing man-in-the-middle attacks) and verifies the sender's identity.
  • STS (Security Token Service): When using short-lived credentials (such as those generated by AWS SSO or IAM Role assumption), the CLI interacts with STS to obtain temporary access keys, secret keys, and session tokens. These tokens automatically expire, reducing the blast radius of a compromised credential.
  • API Endpoints: By default, the AWS CLI targets the public regional endpoints of AWS services (e.g., https://ec2.us-east-1.amazonaws.com). In highly secure enterprise environments, these can be overridden to route traffic through private VPC Endpoints (PrivateLink), keeping API traffic entirely within the AWS private backbone network.

5. Comprehensive Installation & Cryptographic Verification

Installing software on engineer workstations presents a significant supply-chain risk. To maintain enterprise compliance (such as SOC2 or ISO 27001), you must verify the cryptographic signatures of the AWS CLI installer before execution.

Option A: Linux x86_64 & ARM64 Native Installation

The following script downloads, cryptographically verifies, and installs the AWS CLI v2 on a Linux system. It uses the AWS public GPG key to verify that the downloaded package has not been altered.

#!/usr/bin/env bash
set -euo pipefail

# Define variables
INSTALL_DIR="/usr/local/aws-cli"
BIN_DIR="/usr/local/bin"
TMP_DIR=$(mktemp -d)

echo "Created temporary directory: ${TMP_DIR}"
cd "${TMP_DIR}"

# 1. Download the AWS CLI v2 installer and its signature file
echo "Downloading AWS CLI v2 installer..."
curl -s "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
curl -s "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip.sig" -o "awscliv2.sig"

# 2. Import the AWS CLI public GPG key
# Key ID: 3701 AC11 8965 0270 F0A2  08AF D72C 5D74 36CD DBB2
echo "Importing AWS public GPG key..."
cat <<EOF > aws-public-key.gpg
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.7 (GNU/Linux)

mQENBFY4W7cBCADmXQv1aO5E35vXvIEXvW4p3G1vA7W9vUvI8lK8X2V6Jv7XmZ3N
... [Truncated for readability] ...
-----END PGP PUBLIC KEY BLOCK-----
EOF

# For production, fetch directly from a trusted key server or use local known keys
gpg --import aws-public-key.gpg

# 3. Verify the signature
echo "Verifying cryptographic signature..."
if gpg --verify awscliv2.sig awscliv2.zip; then
    echo "SUCCESS: Cryptographic signature verified. Proceeding with installation."
else
    echo "CRITICAL ERROR: Signature verification failed! The file may have been compromised." >&2
    exit 1
fi

# 4. Extract and install
echo "Extracting package..."
unzip -q awscliv2.zip

echo "Installing AWS CLI..."
sudo ./aws/install --install-dir "${INSTALL_DIR}" --bin-dir "${BIN_DIR}" --update

# 5. Clean up
cd /
rm -rf "${TMP_DIR}"

# 6. Verify installation
aws --version

Option B: macOS Installation (M1/M2/M3 Apple Silicon & Intel)

On macOS, the preferred installation method is using the native installer package. We can verify the package signature using macOS's built-in pkgutil tool.

# Download the macOS PKG installer
curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"

# Verify the cryptographic signature of the PKG file
pkgutil --check-signature AWSCLIV2.pkg

# Expected Output should contain:
# Developer ID Installer: Amazon Web Services, Inc. (949DB67YNS)
# Authority: Developer ID Certification Authority
# Authority: Apple Root CA

# Install the package
sudo installer -pkg AWSCLIV2.pkg -target /

Option C: Windows Installation via PowerShell

For Windows workstations, we leverage PowerShell to download and execute the MSI installer silently, ensuring the installation is repeatable across enterprise fleets.

# Download the MSI Installer
Invoke-WebRequest -Uri "https://awscli.amazonaws.com/AWSCLIV2.msi" -OutFile "AWSCLIV2.msi"

# Verify the digital signature of the MSI
(Get-AuthenticodeSignature .\AWSCLIV2.msi).SignerCertificate | Format-List

# Run the installer silently
Start-Process msiexec.exe -ArgumentList '/i AWSCLIV2.msi /qn /norestart' -Wait

# Refresh environment variables and verify
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
aws --version

6. Modern Authentication: Configuring AWS IAM Identity Center (SSO)

Using long-lived IAM user access keys (AKIA...) on local workstations is a critical security risk. If a laptop is compromised, or if an engineer accidentally commits these keys to a public repository, the entire AWS environment can be compromised.

The modern enterprise standard is AWS IAM Identity Center (formerly AWS Single Sign-On). This mechanism authenticates users via their enterprise Identity Provider (such as Okta, Azure AD, or Ping Identity) and issues short-lived temporary security credentials directly to the local ~/.aws/sso/cache directory.

Step-by-Step IAM Identity Center Integration

To configure your local AWS CLI to use AWS IAM Identity Center, follow this interactive setup process.

Step 1: Run the Interactive SSO Wizard

aws configure sso

Step 2: Provide the Enterprise SSO Parameters

The wizard will prompt you for the following parameters. Replace the placeholder values with your organization's actual configuration:

  • SSO session name: Give a descriptive name to your session (e.g., enterprise-sso).
  • SSO start URL: The landing page URL provided by your administrator (e.g., https://my-org.awsapps.com/start).
  • SSO region: The AWS Region where your Identity Center is deployed (e.g., us-east-1).
  • SSO registration scopes: Press Enter to accept the default scopes (sso:account:access).

At this point, the AWS CLI will automatically open your default web browser. You will be prompted to log in to your Identity Provider and authorize the AWS CLI request.

Step 3: Select Your Target Account and IAM Role

Once authenticated in the browser, the CLI will query your authorized accounts and roles, presenting them in an interactive list:

Authorized accounts:
> 111122223333 (Enterprise-Production)
  444455556666 (Enterprise-Staging)
  777788889999 (Enterprise-Sandbox)

Select an account: 111122223333
There are 2 roles available to you:
> AdministratorAccess
  ReadOnlyAccess

Select a role: AdministratorAccess
CLI default client Region [us-east-1]: us-east-1
CLI default output format [json]: json
CLI profile name [AdministratorAccess-111122223333]: prod-admin

The Resulting Configuration Files

The wizard automatically writes the configuration to your local ~/.aws/config file. Let's examine how a multi-profile configuration is structured for enterprise use cases:

# File: ~/.aws/config

# Define the shared SSO session parameters
[sso-session enterprise-sso]
sso_start_url = https://my-org.awsapps.com/start
sso_region = us-east-1
sso_registration_scopes = sso:account:access

# Production Administrator Profile
[profile prod-admin]
sso_session = enterprise-sso
sso_account_id = 111122223333
sso_role_name = AdministratorAccess
region = us-east-1
output = json

# Staging Developer Profile
[profile staging-dev]
sso_session = enterprise-sso
sso_account_id = 444455556666
sso_role_name = PowerUserAccess
region = us-west-2
output = json

# Sandbox Read-Only Profile
[profile sandbox-read]
sso_session = enterprise-sso
sso_account_id = 777788889999
sso_role_name = ReadOnlyAccess
region = us-east-1
output = yaml

Logging In and Out

Once configured, engineers no longer need to manage credentials manually. To authenticate at the start of a workday:

# Log in to the SSO session (authenticates all associated profiles)
aws sso login --sso-session enterprise-sso

# Test access to the production profile
aws sts get-caller-identity --profile prod-admin

# Log out and invalidate local cached tokens
aws sso logout

To learn more about secure identity management, see our comprehensive guide on AWS IAM Policies and Security Best Practices.


7. Deep Dive: AWS CLI Mechanics & Advanced JMESPath Querying

An expert DevOps engineer must be highly efficient at querying and parsing complex AWS responses. Running a command and piping the output to grep or awk is fragile and slow. Instead, the AWS CLI integrates JMESPath (a query language for JSON) natively via the --query parameter. JMESPath operations are executed client-side, enabling robust filtering, projections, and formatting.

Understanding Command Structure

Every AWS CLI command follows a strict hierarchical syntax:

aws <service> <operation> [parameters] [--query "expression"] [--output format]

JMESPath Syntax Reference Table

Use this reference table to master common JMESPath syntax patterns:

Pattern JMESPath Syntax Description
Identifier Reservations Selects the value associated with the key Reservations.
Flattening Reservations[*].Instances[*] Flattens nested arrays of instances across multiple reservations.
Filtering [?State.Name=='running'] Filters elements in an array based on a boolean condition.
Projection {ID: InstanceId, Type: InstanceType} Creates a new custom JSON object with specified keys.
Multi-select List [InstanceId, State.Name] Extracts values into a simplified flat array.
Functions length(Instances) or contains(Tags[].Key, 'Env') Applies built-in functions to analyze arrays or strings.

Advanced Querying Scenarios (Real-World Examples)

Let's look at practical, highly complex querying scenarios that DevOps engineers encounter daily.

Scenario 1: Find all running EC2 instances, returning only their InstanceId, Public IP, and Name Tag

This query flattens the EC2 response, filters for running states, and constructs a clean, custom JSON output.

aws ec2 describe-instances \
  --profile prod-admin \
  --query "Reservations[*].Instances[?State.Name=='running'].{InstanceID: InstanceId, PublicIP: PublicIpAddress, Name: Tags[?Key=='Name'].Value | [0]}" \
  --output json

Scenario 2: List all IAM Users without Multi-Factor Authentication (MFA) enabled

This query is critical for security auditing. It checks the virtual MFA devices and cross-references active users.

# Step 1: List all virtual MFA devices and extract associated usernames
MFA_USERS=$(aws iam list-virtual-mfa-devices --query "VirtualMFADevices[*].User.UserName" --output text)

# Step 2: List all users not in that list
aws iam list-users --query "Users[?!contains('${MFA_USERS}', UserName)].UserName" --output json

Scenario 3: Find the oldest 5 Amazon Machine Images (AMIs) owned by your account

Useful for automated cleanup and cost-optimization scripts. This query sorts images by creation date and slices the array.

aws ec2 describe-images \
  --owners self \
  --query "sort_by(Images, &CreationDate)[:5].{ID: ImageId, Name: Name, Created: CreationDate}" \
  --output table

Server-Side Filtering vs. Client-Side Filtering

It is vital to understand the difference between --filter (server-side) and --query (client-side).

  • Server-Side Filtering (--filter / --filters): This sends filtering parameters to the AWS API endpoint. The AWS control plane processes the filter and returns *only* matching records. This reduces network payload size, prevents API throttling, and increases execution speed. Rule of thumb: Always use server-side filters first if the API supports them.
  • Client-Side Filtering (--query): This downloads the entire, unfiltered JSON payload from AWS and filters it locally in your workstation's memory. This is highly flexible and supports complex logic, but can be slow and trigger rate-limiting if used on large-scale datasets.

Example of combining both for maximum efficiency:

# Server-side filter restricts the download to 't3.micro' instances.
# Client-side query extracts only the Instance ID.
aws ec2 describe-instances \
  --filters "Name=instance-type,Values=t3.micro" \
  --query "Reservations[*].Instances[*].InstanceId" \
  --output text

8. Enterprise Security Hardening & Credential Protection

Securing local developer environments is just as important as securing your production servers. If an attacker gains access to a developer's machine, they will target the AWS CLI configurations. Below are enterprise best practices for securing local developer setups.

1. Never Use Hardcoded Credentials

Avoid writing access keys directly into the ~/.aws/credentials file. If your organization has not yet adopted IAM Identity Center, use AWS Vault to store credentials securely in your operating system's native keychain (such as macOS Keychain, Windows Credential Manager, or GNOME Keyring).

2. Use AWS Vault for Secure Key Storage

AWS Vault is an open-source tool that encrypts your credentials and exposes them to the AWS CLI as temporary environment variables.

# Install AWS Vault on macOS via Homebrew
brew install --cask aws-vault

# Add a profile's credentials securely to the OS keychain
aws-vault add prod-developer

# Execute an AWS CLI command securely using those credentials
aws-vault exec prod-developer -- aws s3 ls

3. Implement Git-Secrets to Prevent Credential Leaks

Accidentally committing AWS credentials to GitHub or GitLab is a common cause of cloud security breaches. To prevent this, install and configure git-secrets on all developer workstations to scan commits before they are pushed.

# Install git-secrets (macOS example)
brew install git-secrets

# Configure git-secrets globally
git secrets --register-aws --global

# Install hooks into a specific repository
cd /path/to/your/git/repo
git secrets --install

# Scan the existing repository for secrets
git secrets --scan

4. Restrict Directory Permissions

Ensure that your local AWS configuration directories are restricted to your specific system user. Run the following commands to secure these folders on Linux and macOS:

chmod 700 ~/.aws
chmod 600 ~/.aws/config
chmod 600 ~/.aws/credentials

9. Setting Up Session Manager & Developer Utilities

Modern cloud architectures avoid exposing SSH ports (TCP/22) to the public internet. Instead, engineers use AWS Systems Manager (SSM) Session Manager to establish secure, audited shell access to EC2 instances and ECS containers. This requires installing the Session Manager plugin on your local workstation.

Installing the Session Manager Plugin

For Debian/Ubuntu Linux:

# Download the Debian package
curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/ubuntu_64bit/session-manager-plugin.deb" -o "session-manager-plugin.deb"

# Install the package
sudo dpkg -i session-manager-plugin.deb

# Verify installation
session-manager-plugin

For macOS:

# Download the zip archive
curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/mac/sessionmanager-bundle.zip" -o "sessionmanager-bundle.zip"

# Unzip and run the installer
unzip sessionmanager-bundle.zip
sudo ./sessionmanager-bundle/install -i /usr/local/sessionmanagerplugin -b /usr/local/bin/session-manager-plugin

# Verify installation
session-manager-plugin

Using Session Manager in Production

Once the plugin is installed, you can start a secure terminal session with any EC2 instance that has the SSM Agent running and is authorized by IAM. No SSH keys or open inbound security group rules are required.

# Start a shell session on a target instance
aws ssm start-session --target i-0123456789abcdef0 --profile prod-admin

# Tunnel a local port to a remote service (e.g., access a private RDS database)
aws ssm start-session \
  --target i-0123456789abcdef0 \
  --document-name AWS-StartPortForwardingSession \
  --parameters '{"portNumber":["5432"],"localPortNumber":["5432"]}' \
  --profile prod-admin

Setting Up the AWS Cloud Development Kit (CDK)

The AWS CDK allows developers to define cloud infrastructure using familiar programming languages like TypeScript, Python, or Go. Let's install the CDK CLI and bootstrap an environment.

# Install Node.js runtime (required for CDK)
# On macOS/Linux, we recommend using nvm (Node Version Manager)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
source ~/.bashrc
nvm install 20

# Install the AWS CDK CLI globally
npm install -g aws-cdk

# Verify the installation
cdk --version

# Bootstrap your AWS account (provisions resources needed for CDK deployments)
cdk bootstrap aws://111122223333/us-east-1 --profile prod-admin

10. Production-Ready Automation Scripts

In this section, we provide two production-grade Bash scripts designed for enterprise administration. Both follow scripting best practices, including robust error handling, user input validation, and proper logging.

Script 1: Multi-Region Resource Auditor

This script queries all active AWS regions to find orphaned or running resources (like unattached EBS volumes and running EC2 instances) and exports the data to a clean CSV report.

#!/usr/bin/env bash
# ==============================================================================
# Title:        aws_resource_auditor.sh
# Description:  Audits running EC2 instances and unattached EBS volumes across
#               all enabled AWS regions.
# Author:       Enterprise DevOps Engineering
# Usage:        ./aws_resource_auditor.sh -p <aws-profile>
# ==============================================================================

set -euo pipefail

# Default values
AWS_PROFILE=""
OUTPUT_FILE="aws_resource_audit_$(date +%Y%m%d_%H%M%S).csv"

log() {
    echo -e "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $1"
}

usage() {
    echo "Usage: $0 -p <aws-profile>" >&2
    exit 1
}

# Parse command line options
while getopts "p:h" opt; do
    case "${opt}" in
        p) AWS_PROFILE="${OPTARG}" ;;
        h|*) usage ;;
    esac
done

if [ -z "${AWS_PROFILE}" ]; then
    log "ERROR: AWS profile must be specified using the -p flag."
    usage
fi

# Verify the profile works
log "Verifying AWS authentication using profile: ${AWS_PROFILE}..."
if ! aws sts get-caller-identity --profile "${AWS_PROFILE}" >/dev/null 2>&1; then
    log "ERROR: Failed to authenticate with profile '${AWS_PROFILE}'. Please check your credentials."
    exit 1
fi

# Get the list of all active regions
log "Fetching active AWS regions..."
REGIONS=$(aws ec2 describe-regions \
    --profile "${AWS_PROFILE}" \
    --all-regions false \
    --query "Regions[*].RegionName" \
    --output text)

# Initialize the CSV output file
echo "Region,ResourceType,ResourceID,Status,Details" > "${OUTPUT_FILE}"

for REGION in ${REGIONS}; do
    log "Auditing region: ${REGION}..."

    # 1. Audit EC2 Instances
    log " Checking EC2 Instances in ${REGION}..."
    EC2_DATA=$(aws ec2 describe-instances \
        --profile "${AWS_PROFILE}" \
        --region "${REGION}" \
        --query "Reservations[*].Instances[*].[InstanceId, State.Name, InstanceType]" \
        --output text)

    while read -r INSTANCE_ID STATE TYPE; do
        if [ -n "${INSTANCE_ID}" ]; then
            echo "${REGION},EC2,${INSTANCE_ID},${STATE},Type:${TYPE}" >> "${OUTPUT_FILE}"
        fi
    done <<< "${EC2_DATA}"

    # 2. Audit Unattached EBS Volumes
    log " Checking Unattached EBS Volumes in ${REGION}..."
    EBS_DATA=$(aws ec2 describe-volumes \
        --profile "${AWS_PROFILE}" \
        --region "${REGION}" \
        --filters "Name=status,Values=available" \
        --query "Volumes[*].[VolumeId, Size, CreateTime]" \
        --output text)

    while read -r VOLUME_ID SIZE CREATE_TIME; do
        if [ -n "${VOLUME_ID}" ]; then
            echo "${REGION},EBS,${VOLUME_ID},unattached,Size:${SIZE}GB_Created:${CREATE_TIME}" >> "${OUTPUT_FILE}"
        fi
    done <<< "${EBS_DATA}"

done

log "Audit completed successfully. Results exported to: ${OUTPUT_FILE}"

Script 2: Secure Assumed-Role Session Initiator

In highly secure environments, engineers log in to a read-only profile and must assume a privileged IAM Role to make changes. This script automates assuming a role, handles multi-factor authentication (MFA), and exports the temporary session credentials to the active terminal environment.

#!/usr/bin/env bash
# ==============================================================================
# Title:        assume_role_helper.sh
# Description:  Assumes an IAM Role with MFA and exports temporary credentials
#               to the current shell session.
# Usage:        source ./assume_role_helper.sh -r <role-arn> -m <mfa-arn> -p <base-profile>
# ==============================================================================

# Note: This script must be sourced (e.g., 'source ./assume_role_helper.sh')
# to export environment variables to the parent shell.

if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    echo "ERROR: This script must be sourced so it can set environment variables." >&2
    echo "Usage: source $0 -r <role-arn> -m <mfa-arn> -p <base-profile>" >&2
    exit 1
fi

ROLE_ARN=""
MFA_ARN=""
BASE_PROFILE="default"
SESSION_NAME="DeveloperWorkstationSession"

# Parse arguments
while getopts "r:m:p:s:" opt; do
    case "${opt}" in
        r) ROLE_ARN="${OPTARG}" ;;
        m) MFA_ARN="${OPTARG}" ;;
        p) BASE_PROFILE="${OPTARG}" ;;
        s) SESSION_NAME="${OPTARG}" ;;
        *) echo "Invalid option" >&2; return 1 ;;
    esac
done

if [ -z "${ROLE_ARN}" ] || [ -z "${MFA_ARN}" ]; then
    echo "ERROR: Role ARN (-r) and MFA Serial ARN (-m) are required." >&2
    return 1
fi

# Prompt for the MFA token code securely
echo -n "Enter MFA Code for ${MFA_ARN}: "
read -r -s MFA_CODE
echo ""

if [ -z "${MFA_CODE}" ]; then
    echo "ERROR: MFA code cannot be empty." >&2
    return 1
fi

echo "Requesting temporary security credentials..."
TEMP_CREDS=$(aws sts assume-role \
    --profile "${BASE_PROFILE}" \
    --role-arn "${ROLE_ARN}" \
    --role-session-name "${SESSION_NAME}" \
    --serial-number "${MFA_ARN}" \
    --token-code "${MFA_CODE}" \
    --query "Credentials.[AccessKeyId, SecretAccessKey, SessionToken]" \
    --output text)

if [ $? -ne 0 ]; then
    echo "ERROR: Failed to assume role. Verify your input parameters and MFA code." >&2
    return 1
fi

# Parse the tab-delimited response
read -r ACCESS_KEY SECRET_KEY SESSION_TOKEN <<< "${TEMP_CREDS}"

# Export variables to the active terminal environment
export AWS_ACCESS_KEY_ID="${ACCESS_KEY}"
export AWS_SECRET_ACCESS_KEY="${SECRET_KEY}"
export AWS_SESSION_TOKEN="${SESSION_TOKEN}"

echo "SUCCESS: Temporary credentials exported to your active shell session."
echo "Your active identity is now:"
aws sts get-caller-identity

11. Operational Troubleshooting & Debugging

Even properly configured developer tools can encounter issues due to network configurations, permission changes, or expired tokens. This section covers how to diagnose and resolve these common problems.

Using the Global Debug Flag

When an AWS CLI command fails with an ambiguous error, append the --debug flag. This outputs the raw HTTP request payloads, headers, and responses from the AWS endpoints, as well as the internal Python stack traces.

aws s3 ls --debug --profile prod-admin

Warning: The debug output may include sensitive authorization headers. Do not paste raw debug logs into public support forums or shared channels.

Common Error Resolution Matrix

Error Message Root Cause Resolution Action Steps
An error occurred (AccessDenied) when calling the... The IAM User or Role does not have permission to execute the requested API call. Check the IAM Policy associated with your role. Ensure boundary policies or Service Control Policies (SCPs) are not blocking the action.
An error occurred (ExpiredToken) when calling the... The temporary security credentials generated by SSO or STS have expired. Run aws sso login --sso-session <session-name> to refresh your credentials.
SignatureDoesNotMatch: The request signature we calculated does not match... System clock drift on your workstation, or special characters in your secret key. Sync your local workstation's clock using NTP: sudo ntpdate pool.ntp.org or verify your credentials are correct.
Could not connect to the endpoint URL... Workstation has no internet access, or DNS cannot resolve the AWS regional endpoint. Verify your network connection. If working in a private subnet, ensure you have configured custom endpoint overrides or have route access through a NAT Gateway.

Addressing Throttling and API Rate Limits

If you run high-frequency automation scripts, you may receive a ThrottlingException or RequestLimitExceeded error. To handle this, configure the AWS CLI's built-in retry mechanism to use exponential backoff.

Add these configurations to your default settings in ~/.aws/config:

# Enable standard adaptive retries
[default]
retry_mode = adaptive
max_attempts = 10
  • Standard Retry Mode: Retries requests up to a limit, using backoff times that increase with each attempt.
  • Adaptive Retry Mode: Dynamically adjusts the rate of outgoing requests to match the capacity of the target AWS service, helping prevent throttling errors before they occur.

12. Monitoring, Auditing, and Compliance

In enterprise environments, all developer API activity must be logged and monitored for compliance (e.g., SOC2, PCI-DSS). Every action taken using the AWS CLI is recorded in AWS CloudTrail.

How to Audit Local Developer Activity

To inspect API calls executed by a specific developer workstation, you can search CloudTrail events. This is highly useful for security audits or troubleshooting permission issues.

# Query CloudTrail for API calls made by a specific IAM User
aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=Username,AttributeValue=john.doe@enterprise.com \
  --max-results 10 \
  --profile prod-admin

A typical CloudTrail event log includes details like the client IP address (sourceIPAddress), the user agent (e.g., aws-cli/2.15.0), the role assumed, and the specific API parameters used.


13. Enterprise Interview Questions & Answers

Q1: How does the AWS CLI determine which credentials to use when multiple configurations exist? Explain the exact order of precedence.

Answer: The AWS CLI evaluates credentials in a strict, deterministic sequence:
  1. Command Line Options: Explicit parameters like --region, --profile, or --output override all other settings. 2. Environment Variables: AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN AWS_PROFILE AWS_REGION 3. Assume Role Configuration: Role-based profiles configured in ~/.aws/config. 4. IAM Identity Center (SSO) Cached Credentials: Stored within ~/.aws/sso/cache. 5. Shared Credentials File: ~/.aws/credentials 6. Shared Configuration File: ~/.aws/config 7. Container Credentials: ECS Task Roles and EKS IAM Roles for Service Accounts (IRSA). 8. EC2 Instance Metadata Service (IMDS): Instance Profiles attached to EC2 instances. The first valid credential source discovered in this chain is used for authentication.

Q2: Explain the difference between AWS CLI v1 and AWS CLI v2.

Answer: AWS CLI v2 is the modern enterprise standard and provides several improvements:
  • Bundled Python runtime (no dependency conflicts).
  • Native AWS IAM Identity Center (SSO) integration.
  • Interactive auto-prompt mode.
  • Improved binary distribution.
  • Enhanced retry handling.
  • Integrated wizards.
  • Improved security controls.
  • Better support for modern AWS services.
AWS CLI v1 remains functional but is primarily maintained for backward compatibility.

Q3: What is AWS Signature Version 4 (SigV4)?

Answer: AWS Signature Version 4 is the cryptographic signing process used to authenticate AWS API requests. The process involves:
  1. Creating a canonical request.
  2. Hashing request contents using SHA-256.
  3. Generating a string-to-sign.
  4. Deriving a signing key using:
    • Date
    • Region
    • Service
    • AWS Secret Key
  5. Creating the final HMAC signature.
  6. Adding the Authorization header.
AWS validates the signature before authorizing the API request.

Q4: Why should enterprises prefer IAM Identity Center (SSO) over IAM User Access Keys?

Answer: IAM Identity Center provides:
  • Short-lived credentials.
  • Centralized identity management.
  • MFA enforcement.
  • Automatic credential rotation.
  • Federation with Okta, Azure AD, Ping Identity, and other IdPs.
  • Improved auditability.
  • Reduced credential leakage risk.
Long-lived IAM user keys violate modern security best practices and should be eliminated whenever possible.

Q5: How would you securely access an EC2 instance without opening port 22?

Answer: Use AWS Systems Manager Session Manager. Benefits include:
  • No SSH keys required.
  • No inbound security group rules.
  • Full CloudTrail auditing.
  • Encrypted communication channels.
  • Centralized IAM authorization.
  • Port forwarding support.
  • Session recording capabilities.
This approach significantly reduces attack surface compared to traditional SSH access.

14. Frequently Asked Questions (FAQs)

1. Where does AWS CLI store credentials?

Credentials are commonly stored in:

~/.aws/credentials

However, enterprise environments should use:

  • AWS IAM Identity Center (SSO)
  • AWS Vault
  • Role assumption
  • Instance Profiles
instead of static credentials.

2. How can I see which identity I am currently using?

aws sts get-caller-identity

This displays:

  • Account ID
  • User or Role ARN
  • Unique principal identifier

3. How do I switch between AWS profiles?

Option 1:

aws s3 ls --profile prod-admin

Option 2:

export AWS_PROFILE=prod-admin

All subsequent CLI commands will use the selected profile.

4. How do I clear cached SSO credentials?

aws sso logout

This removes cached authentication tokens stored within:

~/.aws/sso/cache

5. What is the safest way to store AWS credentials locally?

Recommended order:

  1. AWS IAM Identity Center (SSO)
  2. AWS Vault
  3. Role Assumption
  4. Instance Profiles
  5. Static Credentials (last resort)

15. Summary & Next Steps

In this lesson, we established a complete enterprise-grade AWS developer workstation and automation environment.

We covered:

  • AWS CLI v2 architecture and request lifecycle
  • Cryptographic installer verification
  • AWS IAM Identity Center (SSO) authentication
  • Advanced JMESPath querying
  • Credential security hardening
  • AWS Vault integration
  • Git secrets protection
  • Session Manager installation and usage
  • AWS CDK setup and bootstrapping
  • Production-grade automation scripts
  • Troubleshooting methodologies
  • CloudTrail auditing and compliance monitoring
  • Enterprise interview preparation

Next Lesson

AWS Identity and Access Management (IAM): Users, Groups, Roles, Policies, Permission Boundaries, SCPs, and Enterprise Security Design

In the next lesson, we will perform a deep dive into AWS IAM architecture, policy evaluation logic, role assumption flows, cross-account trust relationships, Service Control Policies (SCPs), and enterprise-scale identity governance patterns.

About the Author

Naresh Kumar

Naresh Kumar

Senior Java Backend Engineer experienced in Banking, Payments, ISO 20022, Spring Boot, Microservices, Kafka, Docker, Kubernetes, AWS and Cloud Native Systems.

Built enterprise payment solutions, transaction processing systems, API platforms and scalable microservices used in production.

LinkedIn Profile