AWS IAM: Best Practices & Advanced Features
IAM Best Practices
Never use root account: create an admin IAM user or use IAM Identity Center. Lock root credentials away.
Principle of least privilege: start with minimum permissions, add only what's needed. Use Access Analyzer to find unused permissions.
Use roles, not access keys: EC2, Lambda, ECS, etc. can assume roles — no long-lived credentials on instances.
Rotate access keys regularly: audit with aws iam generate-credential-report. Keys older than 90 days are a risk.
Enable MFA everywhere: require MFA for console access and for assuming sensitive roles via Condition: aws:MultiFactorAuthPresent.
Use IAM Identity Center (SSO): centrally manage human access to multiple accounts using your existing identity provider (Okta, Azure AD).
Tag IAM resources: helps with cost allocation, auditing, and ABAC (attribute-based access control).
Monitor with CloudTrail: all IAM API calls are logged. Set up alerts for root login, policy changes, access key creation.
IAM Identity Center (SSO)
IAM Identity Center replaces per-account IAM users for human access:
Setup:
1. Enable IAM Identity Center in AWS Organizations management account
2. Connect identity provider (built-in, Azure AD, Okta, Google Workspace)
3. Create permission sets (like IAM roles)
4. Assign users/groups to accounts with permission sets
Benefits:
- Single sign-on across all AWS accounts
- No long-lived credentials — temporary credentials via portal or CLI
- Centralized access review
- Integrates with standard SAML 2.0 / OIDC IdPs
CLI access with SSO:
aws configure sso
aws sso login --profile my-profile
aws s3 ls --profile my-profileABAC — Attribute-Based Access Control
// Grant access based on resource tags matching user tags
// User has tag: Department=Engineering
// Policy: allow access to resources tagged Department=Engineering
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["ec2:StartInstances", "ec2:StopInstances"],
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
"StringEquals": {
"ec2:ResourceTag/Department": "${aws:PrincipalTag/Department}"
}
}
},
{
"Effect": "Allow",
"Action": "ec2:DescribeInstances",
"Resource": "*"
}
]
}Credentials Chain & SDK Behavior
# AWS SDK credential lookup order:
# 1. Environment variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN
# 2. AWS profile (~/.aws/credentials + ~/.aws/config)
# 3. Web identity token (EKS pods via OIDC)
# 4. EC2 instance metadata (role attached to instance)
# 5. ECS task role
# Configure profiles
aws configure --profile dev
# Stored in ~/.aws/credentials and ~/.aws/config
# Use: AWS_PROFILE=dev aws s3 ls
# aws s3 ls --profile dev
# Assume role profile (auto-refreshes credentials)
# ~/.aws/config:
# [profile prod-readonly]
# role_arn = arn:aws:iam::123456789012:role/ReadOnly
# source_profile = default
# mfa_serial = arn:aws:iam::111122223333:mfa/alice
# role_session_name = alice-prod-session
# duration_seconds = 3600
# Use: aws s3 ls --profile prod-readonly
# SDK will auto-refresh every hour
# Credential report (CSV of all users + key ages)
aws iam generate-credential-report
aws iam get-credential-report --output text --query Content | base64 -dKeep your own version of these notes — editable, searchable, and organised by your stack.
Start free