devops

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. Developers group β†’ AmazonEC2FullAccess policy

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/*"
]
}
]
}
FieldMeaning
EffectAllow or Deny β€” Deny always wins
ActionWhich API calls are permitted, e.g. s3:GetObject
ResourceWhich specific resources the action applies to (ARN)
ConditionOptional β€” 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

Terminal window
# List all users
aws iam list-users
# Create a user
aws iam create-user --user-name alice
# Create a group and attach a policy
aws iam create-group --group-name Developers
aws iam attach-group-policy \
--group-name Developers \
--policy-arn arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess
# Add user to group
aws 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 role
aws iam attach-role-policy \
--role-name EC2-S3-ReadRole \
--policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

Trust 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:

Terminal window
# List virtual MFA devices
aws 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