Skip to content
beginner Phase 1 · AWS Fundamentals

IAM & Security

Manage users, roles, policies, and best practices for AWS security.

1h 15m
0 problems
Topic Progress 0%

IAM Fundamentals

IAM Fundamentals

AWS Identity and Access Management (IAM) is a web service that helps you securely control access to AWS resources. You use IAM to control who is authenticated (signed in) and authorized (has permissions) to use resources.

IAM Components

Component Description Use Case
Users Individual identities Developers, admins
Groups Collections of users Team-based access
Roles Assumed temporarily EC2, Lambda, cross-account
Policies JSON permission documents Define what actions are allowed

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/*"
      ]
    }
  ]
}

Policy Evaluation Logic

  1. Default deny (implicit)
  2. Explicit deny always wins
  3. No effect is deny
  4. At least one allow is required
# Create an IAM user
aws iam create-user --user-name developer-john

# Create access keys for the user
aws iam create-access-key --user-name developer-john

# List all IAM users
aws iam list-users

Creating and Managing IAM Policies

Creating and Managing IAM Policies

AWS Managed Policies

AWS provides hundreds of managed policies for common use cases:

  • AmazonS3ReadOnlyAccess - Read-only access to S3
  • AmazonEC2FullAccess - Full access to EC2
  • AdministratorAccess - Full access to all services
  • PowerUserAccess - Full access except IAM
# Attach a managed policy to a user
aws iam attach-user-policy \
  --user-name developer-john \
  --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

# Detach a managed policy
aws iam detach-user-policy \
  --user-name developer-john \
  --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

Custom Policies

Create policies in JSON. Use the IAM policy generator or write manually:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowS3BucketAccess",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject"
      ],
      "Resource": "arn:aws:s3:::my-app-bucket/*"
    },
    {
      "Sid": "AllowS3ListBucket",
      "Effect": "Allow",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::my-app-bucket",
      "Condition": {
        "StringLike": {
          "s3:prefix": ["logs/", "uploads/"]
        }
      }
    }
  ]
}

Policy Conditions

"Condition": {
  "IpAddress": {
    "aws:SourceIp": "203.0.113.0/24"
  },
  "StringEquals": {
    "aws:RequestedRegion": "us-east-1"
  },
  "Bool": {
    "aws:MultiFactorAuthPresent": "true"
  }
}

Validate Policies

# Use AWS CLI to validate policy syntax
aws iam simulate-principal-policy \
  --policy-source-arn arn:aws:iam::123456789012:user/developer-john \
  --action-names s3:GetObject s3:PutObject \
  --resource-arns arn:aws:s3:::my-bucket/*

IAM Roles and Use Cases

IAM Roles and Their Use Cases

IAM roles are entities that define a set of permissions for making AWS service requests, but are not associated with a specific user or group. Roles are assumed temporarily.

Role Trust Policy

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

EC2 Instance Role

# Create a role for EC2
aws iam create-role \
  --role-name EC2-S3-Access \
  --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Principal": {"Service": "ec2.amazonaws.com"},
      "Action": "sts:AssumeRole"
    }]
  }'

# Attach S3 read-only policy
aws iam attach-role-policy \
  --role-name EC2-S3-Access \
  --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

# Create instance profile
aws iam create-instance-profile --instance-profile-name EC2-S3-Profile
aws iam add-role-to-instance-profile \
  --instance-profile-name EC2-S3-Profile \
  --role-name EC2-S3-Access

# Attach to EC2 instance
aws ec2 associate-iam-instance-profile \
  --instance-id i-xxx \
  --iam-instance-profile Name=EC2-S3-Profile

Lambda Execution Role

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

Cross-Account Access

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

IAM Best Practices

IAM Best Practices

Security Checklist

  1. Enable MFA on root and privileged accounts
  2. Use roles instead of access keys for EC2/Lambda
  3. Apply least-privilege principle - grant only needed permissions
  4. Rotate credentials regularly
  5. Use IAM Access Analyzer to find unused permissions
# Enable MFA for root account (via console only)
# For IAM users:
aws iam enable-mfa-device \
  --user-name developer-john \
  --serial-number arn:aws:iam::123456789012:mfa/developer-john \
  --authentication-code1 123456 \
  --authentication-code2 789012

# Create access keys (rotate every 90 days)
aws iam create-access-key --user-name developer-john

# Delete old access keys
aws iam delete-access-key \
  --user-name developer-john \
  --access-key-id AKIAIOSFODNN7EXAMPLE

# Review IAM Access Analyzer findings
aws accessanalyzer list-findings --analyzer-arn arn:aws:access-analyzer:us-east-1:123456789012:analyzer/xxx

IAM Groups Structure

├── Admins
│   └── AdministratorAccess policy
├── Developers
│   ├── DeveloperAccess policy
│   └── S3FullAccess policy
├── DataScientists
│   ├── S3ReadOnlyAccess
│   └── SageMakerFullAccess
└── ReadOnly
    └── ReadOnlyAccess policy

Password Policy

# Set account password policy
aws iam update-account-password-policy \
  --minimum-password-length 14 \
  --require-symbols \
  --require-numbers \
  --require-uppercase-characters \
  --require-lowercase-characters \
  --allow-users-to-change-password \
  --max-password-age 90 \
  --password-reuse-prevention 12

IAM Identity Center and Organizations

IAM Identity Center (SSO)

AWS IAM Identity Center (formerly AWS SSO) provides single sign-on to AWS accounts and business cloud applications.

Features

  • Centralized access to multiple AWS accounts
  • SAML 2.0 federation with Active Directory
  • Built-in user management or connect to external IdPs
  • Automatic role assignment based on group membership

Setup Steps

# Enable IAM Identity Center (via console)
# 1. Go to IAM Identity Center console
# 2. Enable Identity Center
# 3. Add users or connect to Active Directory
# 4. Create permission sets
# 5. Assign users to accounts

# Using AWS CLI:
# Create a permission set
aws sso-admin create-permission-set \
  --instance-arn arn:aws:sso:::instance/ssoins-xxx \
  --name "DeveloperAccess" \
  --session-duration "PT8H"

# Attach managed policy to permission set
aws sso-admin attach-managed-policy-to-permission-set \
  --instance-arn arn:aws:sso:::instance/ssoins-xxx \
  --permission-set-arn arn:aws:sso:::permission-set/ssoins-xxx/ps-xxx \
  --managed-policy-arn arn:aws:iam::aws:policy/PowerUserAccess

AWS Organizations

# Create an organization
aws organizations create-organization --feature-set ALL

# Create a new account under the organization
aws organizations create-account \
  --email dev-team@example.com \
  --account-name "Development" \
  --role-name OrganizationAccountAccessRole

# List accounts
aws organizations list-accounts

# Apply Service Control Policy (SCP)
aws organizations attach-policy \
  --policy-id p-xxx \
  --target-id 123456789012

SCP Example

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyLeaveOrganization",
      "Effect": "Deny",
      "Action": "organizations:LeaveOrganization",
      "Resource": "*"
    },
    {
      "Sid": "DenyRootUser",
      "Effect": "Deny",
      "Action": "*",
      "Resource": "*",
      "Condition": {
        "StringLike": {
          "aws:PrincipalArn": "arn:aws:iam::*:root"
        }
      }
    }
  ]
}