You are viewing a preview of this lesson. Sign in to start learning
Back to Mastering AWS

Identity & Access Management

IAM, Identity Center, permission boundaries, and least privilege principles

AWS Identity & Access Management Fundamentals

Master AWS Identity & Access Management (IAM) with free flashcards and interactive practice to solidify your understanding. This lesson covers IAM users, groups, roles, policies, multi-factor authentication, and security best practicesโ€”essential concepts for securing AWS resources and passing AWS certification exams.

Welcome ๐Ÿ‘‹

Welcome to the foundation of AWS security! Identity & Access Management (IAM) is the service that controls who can access what in your AWS environment. Whether you're managing a single developer account or a multi-team enterprise infrastructure, IAM is your first line of defense and the cornerstone of AWS security architecture.

Think of IAM as the security guard, keycard system, and access logs for your AWS accountโ€”all rolled into one powerful service. Every AWS resource interaction goes through IAM's permission checks, making it absolutely critical to understand.

๐Ÿ’ก Did you know? IAM is one of the few AWS services that's completely freeโ€”there's no charge for creating users, groups, roles, or policies, no matter how many you have!

Core Concepts ๐Ÿ”

What is IAM?

IAM (Identity & Access Management) is a web service that helps you securely control access to AWS resources. IAM enables you to manage authentication (who can sign in) and authorization (what they can do) for your AWS account.

๐ŸŽฏ IAM's Core Purpose

AuthenticationVerify identity ("Who are you?")
AuthorizationGrant permissions ("What can you do?")
AuditTrack activity ("What did you do?")

The Four Pillars of IAM ๐Ÿ›๏ธ

IAM revolves around four fundamental components:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚         IAM COMPONENT HIERARCHY             โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                             โ”‚
โ”‚  ๐Ÿ‘ค USERS โ†’ Individual people or apps      โ”‚
โ”‚     โ”‚                                       โ”‚
โ”‚     โ”œโ”€โ”€โ†’ ๐Ÿ‘ฅ GROUPS (collection of users)   โ”‚
โ”‚     โ”‚                                       โ”‚
โ”‚     โ””โ”€โ”€โ†’ ๐Ÿ“‹ POLICIES (permissions)         โ”‚
โ”‚                โ”‚                            โ”‚
โ”‚                โ””โ”€โ”€โ†’ ๐ŸŽญ ROLES               โ”‚
โ”‚                    (temporary access)       โ”‚
โ”‚                                             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
1. IAM Users ๐Ÿ‘ค

An IAM user represents a person or application that interacts with AWS. Each user has:

  • Unique credentials (username/password for console, access keys for API/CLI)
  • Individual permissions (what they can do)
  • Permanent identity (exists until deleted)

Real-world analogy: Think of an IAM user like an employee badge at a companyโ€”it uniquely identifies someone and determines which doors they can open.

{
  "UserName": "alice-developer",
  "UserId": "AIDACKCEVSQ6C2EXAMPLE",
  "Arn": "arn:aws:iam::123456789012:user/alice-developer",
  "CreateDate": "2024-01-15T10:30:00Z"
}

Best Practice: Create individual IAM users for each personโ€”never share credentials! Even in small teams, each developer should have their own user account.

2. IAM Groups ๐Ÿ‘ฅ

An IAM group is a collection of users. Groups let you manage permissions for multiple users at once.

Key characteristics:

  • Groups contain users (not other groups)
  • Users can belong to multiple groups
  • Groups cannot be nested
  • Groups don't have credentialsโ€”only users do
Example Organization:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Developers โ”‚     โ”‚    Admins   โ”‚     โ”‚   Analysts  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค     โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค     โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ โ€ข Alice     โ”‚     โ”‚ โ€ข Bob       โ”‚     โ”‚ โ€ข Carol     โ”‚
โ”‚ โ€ข David     โ”‚     โ”‚ โ€ข Alice     โ”‚     โ”‚ โ€ข Eve       โ”‚
โ”‚ โ€ข Frank     โ”‚     โ”‚             โ”‚     โ”‚             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
      โ†“                   โ†“                   โ†“
 [Read/Write         [Full Access]      [Read Only
  EC2, S3]                               Analytics]

Best Practice: Organize users into groups based on job function (Developers, QA, Operations) rather than projects. Attach policies to groups, not individual users.

3. IAM Policies ๐Ÿ“‹

An IAM policy is a JSON document that defines permissions. Policies answer the question: "What actions are allowed or denied on which resources?"

Policy structure:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::my-bucket/*"
    }
  ]
}

Policy components:

ComponentPurposeExample
EffectAllow or Deny"Allow", "Deny"
ActionWhat operations"s3:GetObject", "ec2:StartInstances"
ResourceWhich AWS resources"arn:aws:s3:::bucket-name/*"
Condition (optional)When it appliesIP address, time of day, MFA

Types of policies:

  1. Managed Policies (AWS or customer-managed)

    • Standalone policies you can attach to multiple users/groups/roles
    • Reusable and centrally managed
    • Example: AmazonS3ReadOnlyAccess
  2. Inline Policies

    • Embedded directly in a single user, group, or role
    • Deleted when the identity is deleted
    • Use sparinglyโ€”managed policies are preferred

๐Ÿง  Memory Device: "PARC" - Policy, Action, Resource, Conditionโ€”the four elements that define access control.

4. IAM Roles ๐ŸŽญ

An IAM role is an identity with permissions that can be assumed temporarily. Unlike users, roles don't have permanent credentials.

When to use roles:

ROLE USE CASES

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ EC2 Instance needs S3 access           โ”‚
โ”‚    โ”œโ”€โ”€โ†’ Attach IAM role to instance   โ”‚
โ”‚    โ””โ”€โ”€โ†’ No hardcoded credentials! โœ“   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Lambda function needs DynamoDB access  โ”‚
โ”‚    โ”œโ”€โ”€โ†’ Lambda execution role          โ”‚
โ”‚    โ””โ”€โ”€โ†’ Automatic credential rotation โœ“โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Cross-account access                   โ”‚
โ”‚    โ”œโ”€โ”€โ†’ Dev account โ†’ Prod account    โ”‚
โ”‚    โ””โ”€โ”€โ†’ Users assume role temporarily โœ“โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Federated users (SSO, Active Directory)โ”‚
โ”‚    โ”œโ”€โ”€โ†’ External identity provider    โ”‚
โ”‚    โ””โ”€โ”€โ†’ Map to IAM roles automaticallyโœ“โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Real-world analogy: A role is like a visitor badge at a company. You're not a permanent employee, but you can temporarily assume visitor privileges to access specific areas. When you leave, the badge goes back.

{
  "RoleName": "EC2-S3-Access-Role",
  "AssumeRolePolicyDocument": {
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Principal": {"Service": "ec2.amazonaws.com"},
      "Action": "sts:AssumeRole"
    }]
  }
}

Trust policy vs Permission policy:

  • Trust policy (AssumeRolePolicyDocument): Who can assume this role?
  • Permission policy: What can the role do?

Authentication Methods ๐Ÿ”‘

AWS supports multiple authentication mechanisms:

MethodUse CaseSecurity Level
Username/PasswordAWS Management Consoleโญโญ (Basic)
Access KeysCLI, SDK, API callsโญโญ (Basic)
MFAConsole + Access keysโญโญโญโญ (High)
SSO/FederationEnterprise identity systemsโญโญโญโญโญ (Highest)
Access Keys (Programmatic Access)

Access keys consist of:

  • Access Key ID: Like a username (e.g., AKIAIOSFODNN7EXAMPLE)
  • Secret Access Key: Like a password (e.g., wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY)
## Configure AWS CLI with access keys
$ aws configure
AWS Access Key ID: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name: us-east-1
Default output format: json

โš ๏ธ Critical Security Warning: Never commit access keys to version control (GitHub, GitLab). Use environment variables or AWS credential files with restricted permissions.

Multi-Factor Authentication (MFA) ๐Ÿ›ก๏ธ

MFA adds an extra layer of security by requiring:

  1. Something you know (password)
  2. Something you have (MFA device)

MFA device options:

  • Virtual MFA apps (Google Authenticator, Authy, Microsoft Authenticator)
  • Hardware tokens (YubiKey, Gemalto)
  • SMS text message (least secure, not recommended)
{
  "Effect": "Deny",
  "Action": "*",
  "Resource": "*",
  "Condition": {
    "BoolIfExists": {"aws:MultiFactorAuthPresent": "false"}
  }
}

This policy denies all actions unless MFA is presentโ€”enforcing MFA for sensitive operations.

Permission Evaluation Logic ๐Ÿงฎ

When a user attempts an action, AWS evaluates permissions in this order:

PERMISSION EVALUATION FLOWCHART

        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚ Request made    โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                 โ†“
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚ Explicit DENY?  โ”‚โ”€โ”€โ”€โ”€Yesโ”€โ”€โ”€โ†’ โŒ DENIED
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                 โ”‚ No
                 โ†“
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚ Explicit ALLOW? โ”‚โ”€โ”€โ”€โ”€Noโ”€โ”€โ”€โ”€โ†’ โŒ DENIED
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                (Implicit Deny)
                 โ”‚ Yes
                 โ†“
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚ โœ… ALLOWED      โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Key principle: Explicit Deny always wins!

๐Ÿง  Memory Device: "DADI" - Deny Always Dominates, then check for Implicit deny (default).

Detailed Examples ๐Ÿ’ป

Example 1: Creating a Developer with S3 Access

Scenario: You need to give a new developer read/write access to a specific S3 bucket but no access to other AWS services.

Step 1: Create the IAM user

## Using AWS CLI
aws iam create-user --user-name john-developer

Step 2: Create a custom policy

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ListBucket",
      "Effect": "Allow",
      "Action": ["s3:ListBucket"],
      "Resource": "arn:aws:s3:::project-assets-bucket"
    },
    {
      "Sid": "ReadWriteObjects",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject"
      ],
      "Resource": "arn:aws:s3:::project-assets-bucket/*"
    }
  ]
}

Step 3: Attach the policy

aws iam put-user-policy \
  --user-name john-developer \
  --policy-name S3ProjectBucketAccess \
  --policy-document file://s3-policy.json

Why this works:

  • First statement allows listing bucket contents
  • Second statement allows reading, writing, and deleting objects
  • Notice the different Resource ARNs: bucket vs. bucket/*
  • No other AWS services are accessible

Example 2: EC2 Instance Accessing DynamoDB

Scenario: An EC2 instance running your application needs to read/write to a DynamoDB table. You should never store credentials on the instance.

Step 1: Create an IAM role for EC2

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {"Service": "ec2.amazonaws.com"},
    "Action": "sts:AssumeRole"
  }]
}

This trust policy allows EC2 service to assume the role.

Step 2: Create permission policy for DynamoDB

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "dynamodb:GetItem",
      "dynamodb:PutItem",
      "dynamodb:UpdateItem",
      "dynamodb:Query"
    ],
    "Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/UserData"
  }]
}

Step 3: Attach role to EC2 instance

aws iam create-role --role-name EC2-DynamoDB-Role \
  --assume-role-policy-document file://trust-policy.json

aws iam put-role-policy --role-name EC2-DynamoDB-Role \
  --policy-name DynamoDB-Access \
  --policy-document file://dynamodb-policy.json

aws ec2 associate-iam-instance-profile \
  --instance-id i-1234567890abcdef0 \
  --iam-instance-profile Name=EC2-DynamoDB-Role

What happens:

  1. EC2 instance automatically receives temporary credentials
  2. Credentials rotate automatically every few hours
  3. Application uses AWS SDK without hardcoded keys
  4. If instance is compromised, credentials expire quickly

Example 3: Cross-Account Access

Scenario: Your production account (Account A: 111111111111) needs to allow developers from the development account (Account B: 222222222222) to deploy code.

In Production Account (111111111111):

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {"AWS": "arn:aws:iam::222222222222:root"},
    "Action": "sts:AssumeRole",
    "Condition": {
      "StringEquals": {
        "sts:ExternalId": "unique-external-id-12345"
      }
    }
  }]
}

This trust policy allows Account B to assume a role in Account A.

Permission policy (what developers can do in prod):

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "s3:PutObject",
      "lambda:UpdateFunctionCode",
      "cloudformation:UpdateStack"
    ],
    "Resource": [
      "arn:aws:s3:::prod-deployment-bucket/*",
      "arn:aws:lambda:us-east-1:111111111111:function:prod-*",
      "arn:aws:cloudformation:us-east-1:111111111111:stack/prod-*"
    ]
  }]
}

In Development Account (222222222222):

Developers assume the role:

aws sts assume-role \
  --role-arn "arn:aws:iam::111111111111:role/ProdDeploymentRole" \
  --role-session-name "deployment-session" \
  --external-id "unique-external-id-12345"

They receive temporary credentials valid for 1-12 hours.

๐Ÿ’ก Pro tip: The ExternalId prevents the "confused deputy" problemโ€”it ensures only authorized accounts can assume the role, even if the role ARN is known.

Example 4: Enforcing MFA for Sensitive Operations

Scenario: Allow developers to view resources but require MFA for any modification or deletion.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowViewingResources",
      "Effect": "Allow",
      "Action": [
        "ec2:Describe*",
        "s3:List*",
        "s3:Get*",
        "rds:Describe*"
      ],
      "Resource": "*"
    },
    {
      "Sid": "RequireMFAForModifications",
      "Effect": "Allow",
      "Action": [
        "ec2:StartInstances",
        "ec2:StopInstances",
        "ec2:TerminateInstances",
        "s3:PutObject",
        "s3:DeleteObject",
        "rds:DeleteDBInstance"
      ],
      "Resource": "*",
      "Condition": {
        "Bool": {"aws:MultiFactorAuthPresent": "true"}
      }
    },
    {
      "Sid": "DenyAllWithoutMFA",
      "Effect": "Deny",
      "NotAction": [
        "iam:CreateVirtualMFADevice",
        "iam:EnableMFADevice",
        "iam:GetUser",
        "iam:ListMFADevices",
        "iam:ListVirtualMFADevices",
        "iam:ResyncMFADevice"
      ],
      "Resource": "*",
      "Condition": {
        "BoolIfExists": {"aws:MultiFactorAuthPresent": "false"}
      }
    }
  ]
}

How this works:

  1. First statement: Read-only access always allowed
  2. Second statement: Modifications require MFA=true
  3. Third statement: Denies everything except MFA setup if MFA is absent

This forces users to enable MFA before doing anything destructive.

Common Mistakes โš ๏ธ

1. Using Root Account for Daily Operations

โŒ Wrong approach:

## Logging in as root@mycompany.com every day
aws s3 ls --profile root

โœ… Correct approach:

  • Create IAM users with appropriate permissions
  • Enable MFA on root account
  • Store root credentials securely (password manager)
  • Only use root for account-level tasks (billing, account closure)

Why: The root account has unrestricted access to everything. If compromised, an attacker can delete your entire AWS infrastructure, rack up massive bills, or steal all data.

2. Hardcoding Access Keys in Code

โŒ Wrong approach:

import boto3

## NEVER DO THIS!
client = boto3.client(
    's3',
    aws_access_key_id='AKIAIOSFODNN7EXAMPLE',
    aws_secret_access_key='wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'
)

โœ… Correct approach:

import boto3

## Uses IAM role credentials automatically
client = boto3.client('s3')

## Or uses AWS CLI configuration
client = boto3.client('s3')  # Reads from ~/.aws/credentials

Why: Hardcoded credentials in code often end up in version control (Git), leaked on GitHub, or exposed in logs. Use IAM roles for services, environment variables, or credential files with restricted permissions.

3. Overly Permissive Policies

โŒ Wrong approach:

{
  "Effect": "Allow",
  "Action": "*",
  "Resource": "*"
}

This grants full access to everythingโ€”worse than root!

โœ… Correct approach:

{
  "Effect": "Allow",
  "Action": [
    "s3:GetObject",
    "s3:PutObject"
  ],
  "Resource": "arn:aws:s3:::specific-bucket/specific-path/*"
}

Principle of Least Privilege: Grant only the minimum permissions needed to perform a task. Start restrictive and add permissions as needed, not the other way around.

4. Not Rotating Access Keys

โŒ Wrong approach:

  • Creating access keys and using them forever
  • Never checking key age
  • Keeping old keys "just in case"

โœ… Correct approach:

## Check key age
aws iam list-access-keys --user-name john-developer

## Create new key
aws iam create-access-key --user-name john-developer

## Update applications with new key
## Test thoroughly

## Delete old key
aws iam delete-access-key --user-name john-developer --access-key-id AKIAOLD...

Best practice: Rotate access keys every 90 days. Enable AWS Config rule access-keys-rotated to get automatic compliance checks.

5. Confusing Identity-Based vs Resource-Based Policies

Identity-based policies: Attached to users, groups, or roles

{
  "Effect": "Allow",
  "Action": "s3:GetObject",
  "Resource": "arn:aws:s3:::my-bucket/*"
}

Attached to: User/Group/Role โ†’ "What can this identity do?"

Resource-based policies: Attached to resources (S3 buckets, SQS queues)

{
  "Effect": "Allow",
  "Principal": {"AWS": "arn:aws:iam::123456789012:user/alice"},
  "Action": "s3:GetObject",
  "Resource": "arn:aws:s3:::my-bucket/*"
}

Attached to: Resource โ†’ "Who can access this resource?"

Key difference: Resource-based policies specify a Principal (who); identity-based policies don't (they're attached to the "who").

6. Forgetting About Implicit Deny

โŒ Wrong assumption: "If I don't explicitly deny something, it's allowed."

โœ… Reality: By default, everything is denied! You must explicitly allow actions.

DEFAULT STATE: โŒ DENIED
       โ†“
Add ALLOW policy โ†’ โœ… ALLOWED
       โ†“
Add DENY policy โ†’ โŒ DENIED (deny wins)

Security Best Practices ๐Ÿ›ก๏ธ

๐Ÿ”’ IAM Security Checklist

PracticeWhy It Matters
โœ… Enable MFA on root accountPrevents account takeover
โœ… Create individual IAM usersAccountability and audit trail
โœ… Use groups for permissionsEasier management at scale
โœ… Grant least privilegeMinimize damage from compromise
โœ… Use roles for applicationsNo hardcoded credentials
โœ… Enable CloudTrail loggingTrack all IAM actions
โœ… Rotate credentials regularlyLimit window of exposure
โœ… Use policy conditionsContext-aware access control
โœ… Review permissions quarterlyRemove unused access
โœ… Use AWS Organizations SCPsGuardrails across accounts

IAM Policy Simulator ๐Ÿงช

AWS provides a Policy Simulator tool to test policies before deploying:

https://policysim.aws.amazon.com/

Use it to:

  • Test if a user can perform a specific action
  • Understand why an action was denied
  • Validate new policies before attaching them
  • Debug permission issues

๐Ÿ”ง Try this: Paste one of the example policies into the Policy Simulator and test different actions. Change "Allow" to "Deny" and see how evaluation changes.

Key Takeaways ๐ŸŽฏ

๐Ÿ“‹ Quick Reference Card

ConceptSummary
IAM UserPermanent identity with credentials (person/app)
IAM GroupCollection of users; manages permissions at scale
IAM RoleTemporary identity; assumed by users/services
IAM PolicyJSON document defining permissions (PARC)
EffectAllow or Deny (Deny always wins)
PrincipalWho (used in resource-based policies)
ActionWhat operation (service:Operation)
ResourceWhich AWS resource (ARN)
ConditionWhen/how (IP, MFA, time, etc.)
MFATwo-factor authentication for extra security
Access KeysID + Secret for programmatic access
Trust PolicyWho can assume a role
Least PrivilegeMinimum permissions needed
Implicit DenyDefault state; must explicitly allow

Core principles to remember:

  1. Authentication vs Authorization: Who you are vs. what you can do
  2. Explicit Deny > Explicit Allow > Implicit Deny: Permission evaluation order
  3. Use Roles for Services: Never hardcode credentials
  4. Least Privilege Always: Start with minimal access, add as needed
  5. IAM is Free: No excuse not to implement proper security
  6. Enable MFA Everywhere: Especially on root and privileged accounts
  7. Groups for Management: Attach policies to groups, not individual users
  8. Regular Audits: Review and remove unused permissions quarterly

๐Ÿง  Final Memory Device - "IAM SECURE":

  • Identify users uniquely
  • Allow least privilege
  • MFA everywhere
  • Separate duties (groups)
  • Eliminate root usage
  • Check policies with simulator
  • Use roles for services
  • Rotate credentials
  • Enable CloudTrail logging

๐Ÿ“š Further Study

Official AWS Documentation:

Hands-on Practice:

Congratulations! You've completed the IAM fundamentals lesson. Understanding IAM is critical for every AWS service you'll useโ€”it's the foundation of cloud security. Practice creating users, groups, roles, and policies in your AWS account (free tier) to solidify these concepts. Remember: security is not an afterthoughtโ€”it's the first thought! ๐Ÿ”