AWS IAM (Identity and Access Management) is the foundation of all things security in AWS. Whether you're a solo developer, part of a small team, or managing a large-scale infrastructure, IAM best practices can make or break your cloud security.
In this blog, I’ll cover:
IAM concepts you must understand
Real-world IAM configurations
Common mistakes to avoid
A practical security checklist
Hands-on examples for developers and DevOps engineers
Let’s turn your AWS account from “default” to bulletproof.
🧠 What is IAM?
IAM is the AWS service that helps you:
Authenticate who is making a request (identity)
Authorize what that identity can do (access)
It supports:
Users (humans with long-term credentials)
Roles (temporary access for AWS services or external identities)
Groups (collections of users)
Policies (documents that define permissions)
🧱 IAM Components Explained Simply
Component Use Case
User An engineer in your team
Group All backend developers
Role Give Lambda temporary access to S3
Policy “Allow reading from S3 bucket X”
Policies use JSON and follow this structure:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::your-bucket/*"
}
]
}
🔒 Step 1: Secure Your Root Account Immediately
Your AWS root user is the most powerful account. Here's what to do:
✅ Enable MFA (Multi-Factor Authentication)
✅ Don’t use it for daily tasks
✅ Create an IAM user with admin privileges for regular operations
Tip: Use a password manager to store root credentials safely.
👥 Step 2: Create IAM Users and Groups (No Sharing)
Instead of sharing access keys:
Create a separate user for each team member
Assign users to groups like dev, ops, admin
Attach policies to groups — not individual users
aws iam create-group --group-name developers
aws iam add-user-to-group --group-name developers --user-name alice
🛡️ Step 3: Use Roles for Services and Temporary Access
IAM Roles are not tied to a specific user. They are:
Assumed by AWS services (e.g., EC2, Lambda)
Used for federated identities (e.g., SSO or cross-account access)
Example: EC2 Instance Access to S3
Create a role with S3 read access
Attach role to EC2 instance
The EC2 instance automatically gets temporary credentials
🔁 Step 4: Rotate Access Keys and Use IAM Roles for Apps
If you’re storing AWS access keys in:
❌ Source code
❌ GitHub
❌ Hardcoded scripts
… STOP!
Do this instead:
Use IAM roles with temporary credentials
Rotate keys via AWS Secrets Manager
Enable CloudTrail logging to audit credential usage
📄 Step 5: Follow the Principle of Least Privilege (PoLP)
Don’t give “Admin” permissions to every resource.
✅ Give only the permissions the user or service needs
✅ Use IAM Access Analyzer to detect unused permissions
✅ Start with “read-only” access and escalate if necessary
🔐 Example: Read-only Policy for RDS
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds:Describe*",
"cloudwatch:GetMetricData"
],
"Resource": "*"
}
]
}
Attach this to a user who only needs monitoring access.
🚨 Step 6: Enable MFA Everywhere
Use MFA for:
Root account
All IAM users
AWS CLI (aws configure + session-token)
SSO users via external identity providers
MFA options:
Virtual (Google Authenticator, Authy)
Hardware (Yubikey)
SMS (less secure)
🔍 Step 7: Monitor IAM Activity
IAM changes are sensitive. Use these tools:
CloudTrail → Logs every IAM action
IAM Access Analyzer → Detects unused access
AWS Config → Tracks config drift
Trusted Advisor → Flags security risks
Example: Query who made a policy change in the last 24 hours:
aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=PutUserPolicy
🧪 Step 8: Test Permissions Safely
Use the IAM Policy Simulator:
Test if a user/role has access before deploying
Avoid downtime due to incorrect permissions
Also:
Use DryRun in AWS CLI:
aws ec2 start-instances --instance-ids i-12345 --dry-run
🧰 Step 9: Use Service Control Policies (SCP) for Org-Wide Control
If you're using AWS Organizations:
SCPs allow you to restrict what accounts can do even if a user has admin
Great for child accounts (dev, test)
Example: Block EC2 usage in dev account:
{
"Effect": "Deny",
"Action": "ec2:",
"Resource": ""
}
🧼 Step 10: Periodic IAM Cleanup
Don’t let your IAM become the “junk drawer” of AWS.
Schedule monthly cleanup tasks:
✅ Remove inactive users
✅ Revoke unused keys
✅ Rotate credentials
✅ Review attached policies
✅ Delete test roles
Use this script to find users who haven’t logged in:
aws iam get-user --user-name alice
aws iam generate-credential-report
🧾 IAM Security Checklist
✅ Task Description
Root MFA Enabled Absolute must
IAM Users Created No sharing of credentials
Groups Used For scalable access control
Roles Used Temporary access only
Least Privilege No wide-open * policies
MFA Everywhere For users + services
Monitor Changes CloudTrail, Config, Access Analyzer
Rotate Keys At least every 90 days
Cleanup Old Users Monthly checkup
SCP Applied Restrict dev/test accounts
🔚 Final Thoughts
IAM is not optional — it’s the backbone of cloud security.
Whether you’re building apps, deploying ML models, or running Kubernetes clusters — IAM determines what has access to what. A single misconfigured policy could expose your data, shut down your environment, or worse.
Start small, review regularly, and automate wherever possible.
📢 Let's Chat
Have you implemented IAM best practices in your AWS environment?
What worked well — and what didn’t?
Drop your experiences in the comments. Let’s make cloud security a habit, not an afterthought.