IAM Basics
Users, groups, roles, and policies β controlling who can do what in AWS
What is IAM?
AWS Identity and Access Management (IAM) controls who can do what in your AWS account. Every API call β whether from the console, CLI, or code β is authenticated and authorized through IAM.
IAM is global β itβs not tied to a specific region.
Core Components
Users
A person or application with a permanent identity in your AWS account.
- Has a username + password (for console) and/or access keys (for CLI/API)
- Best practice: no users for applications β use roles instead
Groups
A collection of users. Attach policies to a group and all members inherit those permissions.
- e.g.
Developersgroup βAmazonEC2FullAccesspolicy
Roles
An identity with permissions that can be assumed by trusted entities β EC2 instances, Lambda functions, other AWS accounts, or federated users.
- No permanent credentials β temporary security tokens are issued automatically
- Always prefer roles over long-lived access keys for AWS services
Policies
JSON documents that define permissions. Attached to users, groups, or roles.
Policy Structure
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowS3Read", "Effect": "Allow", "Action": [ "s3:GetObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::my-bucket", "arn:aws:s3:::my-bucket/*" ] } ]}| Field | Meaning |
|---|---|
Effect | Allow or Deny β Deny always wins |
Action | Which API calls are permitted, e.g. s3:GetObject |
Resource | Which specific resources the action applies to (ARN) |
Condition | Optional β add conditions like IP, MFA, time |
Least Privilege Principle
Only grant the minimum permissions needed to do the job.
Start with nothing, add permissions as needed. Never use "Action": "*" or "Resource": "*" unless absolutely necessary.
Common CLI Commands
# List all usersaws iam list-users
# Create a useraws iam create-user --user-name alice
# Create a group and attach a policyaws iam create-group --group-name Developersaws iam attach-group-policy \ --group-name Developers \ --policy-arn arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess
# Add user to groupaws iam add-user-to-group --user-name alice --group-name Developers
# Create an IAM role (requires a trust policy JSON file)aws iam create-role \ --role-name EC2-S3-ReadRole \ --assume-role-policy-document file://trust-policy.json
# Attach a policy to a roleaws iam attach-role-policy \ --role-name EC2-S3-ReadRole \ --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccessTrust Policy (for Roles)
A trust policy defines who can assume the role. Example β allow EC2 to assume a role:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ]}Attach this role to an EC2 instance β the instance can now call AWS APIs without any hardcoded credentials.
MFA (Multi-Factor Authentication)
Always enable MFA on the root account and all IAM users with console access:
# List virtual MFA devicesaws iam list-virtual-mfa-devices
# Enforce MFA β add a condition to your policies:"Condition": { "BoolIfExists": { "aws:MultiFactorAuthPresent": "true" }}IAM Best Practices Checklist
- Lock down the root account β enable MFA, donβt use it daily
- Create individual IAM users β never share credentials
- Use groups to assign permissions
- Prefer roles over access keys for applications
- Rotate access keys regularly (or eliminate them)
- Enable IAM credential reports to audit usage
- Apply least privilege everywhere
- Enable CloudTrail to log all API activity