What is IAM? AWS Identity & Access Management Explained

IAM is AWS's version of Linux users, groups, and permissions — scaled to the entire cloud. Learn IAM Users, Groups, Roles, and Policies with the mental model you already know.

Side-by-side comparison of Linux identity (User/Group/Permissions) and AWS IAM (User/Group/Policy/Role/Resource), showing they use the same mental model
📧

Get weekly IT guides

Join 5,000+ IT professionals

Subscribe Free

You just got your first AWS account. You log in, set up an EC2 server, and then someone says: “Don’t use the root account. Create an IAM user.”

Then later: “Attach the S3 policy to the developers group.”

Then: “The Lambda needs a role with DynamoDB access.”

If you’ve been following this series, you already understand all of this. IAM is the same mental model you learned on Linux — Users, Groups, Permissions, Resources — scaled to the entire cloud. Let’s prove it.

IAM in One Paragraph

IAM stands for Identity and Access Management. It’s the AWS service that answers one question for every action in your AWS account:

“Who is allowed to do what, on which resources?”

Every API call to AWS — every aws s3 cp, every EC2 launch, every Lambda invocation — is checked against IAM before it’s allowed. IAM is the security layer between every identity and every resource in AWS.

🔑 The Mental Model Bridge

If you know Linux identity:

LinuxAWS IAM
User (shekhar, UID 1001)IAM User
Group (developers)IAM Group
Permission (chmod, sudoers)IAM Policy (JSON)
rootAWS Root Account / Admin Role
Service account (www-data)IAM Role
Resource (file, directory)AWS Resource (S3, EC2, RDS)

Same concept. Different syntax. That’s it.


The 4 Core IAM Concepts

1. IAM Users — The Individual Identity

An IAM User is a named identity that belongs to your AWS account. Like a Linux user, it has:

  • A username (e.g., shekhar-admin)
  • Credentials: a password (for Console login) and/or Access Keys (for CLI/API)
  • Permissions attached via policies
Linux:   shekhar   → UID 1001 → password in /etc/shadow
AWS IAM: shekhar   → AccessKeyID + SecretAccessKey
The Root Account Is Like Running as Linux root — All the Time

When you create an AWS account, you get a root account — just like Linux root (UID 0). It can do everything with zero restrictions: create users, delete databases, close the account.

Never use the root account for day-to-day work. Create a separate IAM admin user immediately after account creation, then lock the root account away. Store root credentials offline.

This is the same rule as Linux: don’t work as root. Use sudo (IAM with Admin policy) instead.

2. IAM Groups — The Team Identity

An IAM Group is a collection of IAM Users. You attach policies to the group — every user in the group inherits them.

Real example:

  • Group Developers → has AmazonS3FullAccess + AmazonEC2ReadOnlyAccess policies
  • Add alice, bob, charlie to the group
  • All three can now access S3 and read EC2 — without setting permissions per user
# This is conceptually identical to Linux:
sudo groupadd developers
sudo usermod -aG developers alice

# In AWS, you'd use the Console or CLI:
aws iam create-group --group-name Developers
aws iam add-user-to-group --user-name alice --group-name Developers
IAM Groups vs Linux Groups — One Key Difference

Linux groups can grant access to files via chmod. IAM Groups work by attaching JSON policy documents that define allowed API actions.

The concept is identical. The implementation looks different. A Linux permission is chmod 750. An IAM permission is a JSON document saying "Effect": "Allow", "Action": "s3:*".

3. IAM Policies — The Permission Documents

An IAM Policy is a JSON document that says: “Who can do what action on which resource.”

Annotated IAM Policy JSON with Effect, Action, and Resource fields highlighted and explained, with the Principle of Least Privilege note
An IAM Policy has 3 critical fields: Effect (Allow/Deny), Action (which API calls), and Resource (which ARN the action applies to). Deny always beats Allow.

Every IAM policy has at least these fields:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::my-company-bucket/*"
    }
  ]
}
FieldWhat it means
Effect"Allow" or "Deny". Deny always wins if both match.
ActionWhich API calls are allowed. "s3:GetObject", "ec2:*", "*" (everything — dangerous!)
ResourceThe specific ARN (Amazon Resource Name) the policy applies to. "*" means all resources.
The Default is Deny

In IAM, everything is denied by default. A new IAM user with no policies attached cannot do anything — they can’t even list S3 buckets.

You must explicitly grant permissions. This is the opposite of Linux, where a new user can at minimum read their own files.

This “default deny” is a core cloud security principle.

AWS Managed vs Customer Managed Policies

TypeExamplesWhen to use
AWS ManagedAmazonS3FullAccess, AdministratorAccessQuick starts, standard roles
Customer ManagedYour JSON documentWhen you need precise, least-privilege control
InlineEmbedded directly in a user/groupAvoid — hard to manage and audit

Recommendation for production: always write Customer Managed policies with the minimum required permissions.


4. IAM Roles — The Service Identity (Cloud-Unique Concept)

This is where AWS IAM differs most from Linux. IAM Roles are identities assumed by services — not by people.

Think of it like this:

  • IAM User = a person who logs in with a permanent username and password
  • IAM Role = an identity that a service “puts on” temporarily while doing a task

Real examples:

EC2 instance → assumes IAM Role "ec2-s3-readonly" → can call s3:GetObject
Lambda function → assumes IAM Role "lambda-dynamo-writer" → can call dynamodb:PutItem
GitHub Actions → assumes IAM Role via OIDC → can deploy to ECS
Another AWS account → assumes IAM Role for cross-account access
Roles vs Service Accounts in Linux

The closest Linux equivalent is a service account (www-data, mysql). Both are used so that services run with a specific, limited identity — not as root/admin.

The big difference: Linux service accounts use long-lived credentials (or none). IAM Roles issue temporary security tokens that expire automatically (15 minutes to 12 hours). Much more secure.

Why Roles Over Access Keys?

Bad pattern (Access Keys):
  - Embed ACCESS_KEY_ID + SECRET_ACCESS_KEY in EC2 instance
  - Keys are long-lived (until manually rotated)
  - If server is compromised → permanent credentials leaked

Good pattern (IAM Role):
  - Attach IAM Role to EC2 instance
  - AWS rotates credentials automatically every few hours
  - If server is compromised → keys expire and rotate — attacker's access expires

Rule: Never put Access Keys on a server. Always use IAM Roles for AWS services.


IAM in Practice: Common AWS CLI Commands

Check your current identity:

aws sts get-caller-identity

Show who you're currently authenticated as — your IAM User or Role ARN, Account ID, and User ID

beginner
  • UserId: the unique IAM identifier
  • Account: your 12-digit AWS account number
  • Arn: the full ARN of your current identity
  • If using a Role, the Arn will contain 'assumed-role' in it

List IAM users in your account:

aws iam list-users

List all IAM users in the AWS account (requires IAM read permissions)

beginner
  • Shows UserName, UserId, Arn, and CreateDate
  • MFAEnabled is NOT shown here — check separately
  • If you see many users, some may be unnecessary — audit regularly
  • Replace with: aws iam list-users --output table for a prettier view

Check a user’s policies:

aws iam list-attached-user-policies --user-name alice

List all managed IAM policies attached to user 'alice'

beginner
  • Shows PolicyName and PolicyArn
  • Also check: aws iam list-user-policies --user-name alice (for inline policies)
  • And: aws iam list-groups-for-user --user-name alice (group memberships)
  • To see effective permissions, use IAM Policy Simulator in the AWS Console

Create a new IAM user (CLI):

aws iam create-user --user-name deploy-bot

Create a new IAM user called 'deploy-bot' (for a CI/CD pipeline, for example)

beginner
  • New user has NO permissions — you must attach policies after
  • For programmatic access: aws iam create-access-key --user-name deploy-bot
  • For Console access: aws iam create-login-profile --user-name deploy-bot
  • Better for automation: create an IAM Role with OIDC federation instead

The Principle of Least Privilege

This is the most important IAM rule — and it applies equally to Linux:

Grant only the minimum permissions needed to do the specific job. Nothing more.

In practice:

❌ Bad:  Give a developer AdministratorAccess because it's easy
✅ Good: Give a developer AmazonS3FullAccess + AmazonEC2ReadOnlyAccess

❌ Bad:  Lambda function has AmazonDynamoDBFullAccess
✅ Good: Lambda function has policy: dynamodb:GetItem, dynamodb:PutItem on ONE specific table

❌ Bad:  Resource: "*" (all resources in AWS)
✅ Good: Resource: "arn:aws:s3:::company-data-bucket/*" (one specific bucket)
IAM Policy Simulator — Your Testing Tool

Before deploying an IAM policy, test it in the IAM Policy Simulator: Console → IAM → Policy Simulator

You can test: “If I attach this policy to this user, can they run s3:DeleteObject on this bucket?” — without actually doing it.

Use it every time you write a new policy.


MFA: Adding a Second Factor

Every IAM user (especially admins) should have Multi-Factor Authentication (MFA) enabled. Without it, a leaked password means full account access.

In IAM, you can even write policies that require MFA for sensitive actions:

{
  "Effect": "Deny",
  "Action": "*",
  "Resource": "*",
  "Condition": {
    "BoolIfExists": {
      "aws:MultiFactorAuthPresent": "false"
    }
  }
}

This policy says: “Deny everything if the user didn’t authenticate with MFA.” Combined with an Allow policy, this forces MFA for all admin actions.


Hands-On Challenge

Do this in your AWS account (free tier safe):

  1. Log in as root → IAM → Create an IAM user with AdministratorAccess
  2. Enable MFA on the root account (with a mobile authenticator app)
  3. Log out of root, log in as your new IAM admin user
  4. Create an IAM Group called ReadOnlyGroup
  5. Attach ReadOnlyAccess policy to the group
  6. Create a second IAM user called auditor, add to ReadOnlyGroup
  7. Run: aws iam list-attached-user-policies --user-name auditor — verify they have ReadOnly
  8. Bonus: Use the IAM Policy Simulator to test if auditor can delete an S3 bucket (they shouldn’t be able to)

Key Takeaways

  1. IAM = Linux identity model at cloud scale. Users, Groups, Permissions, Resources — same model, JSON syntax.
  2. Everything is denied by default. Permissions must be explicitly granted. No grants = no access.
  3. IAM Roles are for services — EC2, Lambda, ECS. Never embed Access Keys in servers. Use Roles instead.
  4. Deny always beats Allow — if two policies conflict, the explicit Deny wins.
  5. Principle of Least Privilege — minimum permissions, specific resources, specific actions. Always.
  6. MFA is mandatory for humans — especially root and admin users. With MFA a leaked password is useless.
  7. Use AWS Managed policies to start, Customer Managed for production — built-in policies are convenient but often too broad for production.
You Now Know

How IAM connects directly to the Linux identity model you already understand. IAM Users, Groups, Policies, and Roles map 1-to-1 to concepts you’ve already mastered — now they just operate on cloud resources instead of files. You can navigate an AWS account’s permission structure, read any IAM policy, and design secure access patterns with the Principle of Least Privilege.

What’s Next

🧠

Test Your Knowledge

Take a quick 5-question quiz to check your understanding.

📧

Get weekly IT guides

Join 5,000+ IT professionals

Subscribe Free
Type to start searching...