Why the Order Matters
When you run an AWS CLI command or make an SDK call, AWS doesn't just look in one place for credentials. It checks a prioritized list of sources, stopping at the first one that provides valid credentials. Understanding this chain is what separates engineers who debug credential issues in 30 seconds from those who spend 30 minutes confused.
The chain, from highest to lowest priority:
| Priority | Source | Typical Use Case |
|---|---|---|
| 1 | CLI flags (--profile, --region) |
One-off overrides |
| 2 | Environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN, AWS_REGION) |
CI/CD pipelines |
| 3 | AWS SSO session (via aws sso login) |
Modern enterprise SSO |
| 4 | ~/.aws/credentials file | Local development |
| 5 | ~/.aws/config file | Local development |
| 6 | Container credentials (ECS task role via metadata endpoint) | ECS workloads |
| 7 | EC2 Instance Metadata Service (IMDS) (IAM Role attached to instance) | EC2 / Lambda |
The Classic Disaster Scenario
You're working on a Dev task. Two hours ago, you were debugging a Prod issue and ran:
export AWS_ACCESS_KEY_ID=AKIA...PROD
export AWS_SECRET_ACCESS_KEY=...PROD
You forgot to unset those variables. Now you run:
aws s3 rb s3://my-dev-bucket --force
The CLI ignores your ~/.aws/credentials [dev] profile entirely. Environment variables have higher priority. You just deleted a Prod bucket.
Prevention:
# Always check before destructive operations
aws sts get-caller-identity
# Unset environment variable overrides when done
unset AWS_ACCESS_KEY_ID
unset AWS_SECRET_ACCESS_KEY
unset AWS_PROFILE
The Power of the Chain for Portable Code
The chain is also a feature, not just a footgun. If you write SDK code that uses boto3.client('s3') with no explicit credentials, it works correctly:
- On your laptop → picks up
~/.aws/credentials - In a GitHub Actions pipeline → picks up
AWS_ACCESS_KEY_IDenvironment variables injected as secrets - On an EC2 instance → picks up the IAM Role from the Instance Metadata Service
Zero code changes required across all three environments. This portability is the intended design.