Skip to content
CSY302 Week 02 Advanced

Master IAM through hands-on practice—the single most critical cloud security skill.

Cloud & Infrastructure Security

Track your progress through this week's content

Opening Framing

In traditional data centers, network location implied trust—if you could reach a server, you were probably on the internal network and somewhat trusted. Cloud obliterates this assumption. Every resource is accessible via API from anywhere in the world. The only thing standing between an attacker and your crown jewels is identity and access management (IAM).

IAM in the cloud is simultaneously your greatest security control and your greatest risk. Properly configured, it enforces least privilege at a granularity impossible in traditional environments. Misconfigured, a single overprivileged role can expose your entire cloud environment. The complexity of cloud IAM—with its users, groups, roles, policies, permissions, and federation—makes it both powerful and dangerous.

This week covers IAM fundamentals across major cloud providers, policy design and least privilege implementation, role-based access, identity federation, and common IAM vulnerabilities. Mastering IAM is the single most important cloud security skill.

Key insight: Compromise an identity with excessive permissions, and you compromise everything that identity can access.

1) IAM Fundamentals

Cloud IAM systems manage who can do what to which resources:

IAM Core Concepts:

THE IAM QUESTION:
┌─────────────────────────────────────────────────────────────┐
│ Who (Principal) can perform What (Action) on Which (Resource)│
│ under What conditions (Conditions)?                          │
└─────────────────────────────────────────────────────────────┘

PRINCIPALS (Who):
┌─────────────────────────────────────────────────────────────┐
│ Users:                                                      │
│ - Human identities with credentials                         │
│ - Username/password + MFA                                   │
│ - Access keys for programmatic access                       │
│                                                             │
│ Groups:                                                     │
│ - Collections of users                                      │
│ - Permissions assigned to group, inherited by members       │
│ - Simplifies permission management                          │
│                                                             │
│ Roles:                                                      │
│ - Assumable identities (no permanent credentials)           │
│ - Used by services, applications, cross-account             │
│ - Temporary credentials via STS                             │
│                                                             │
│ Service Accounts:                                           │
│ - Machine identities for applications                       │
│ - Non-human principals                                      │
│ - Critical for workload authentication                      │
└─────────────────────────────────────────────────────────────┘

ACTIONS (What):
┌─────────────────────────────────────────────────────────────┐
│ API operations that can be performed                        │
│                                                             │
│ Examples:                                                   │
│ - s3:GetObject (read object from S3)                        │
│ - ec2:StartInstances (start EC2 instance)                   │
│ - iam:CreateUser (create IAM user)                          │
│ - rds:DeleteDBInstance (delete database)                    │
│                                                             │
│ Action Patterns:                                            │
│ - service:Action (specific action)                          │
│ - service:* (all actions in service)                        │
│ - * (all actions—dangerous!)                                │
└─────────────────────────────────────────────────────────────┘

RESOURCES (Which):
┌─────────────────────────────────────────────────────────────┐
│ Specific cloud resources actions apply to                   │
│                                                             │
│ AWS ARN Format:                                             │
│ arn:aws:service:region:account:resource                     │
│                                                             │
│ Examples:                                                   │
│ - arn:aws:s3:::my-bucket/*                                  │
│ - arn:aws:ec2:us-east-1:123456789:instance/*                │
│ - arn:aws:iam::123456789:user/john                          │
│                                                             │
│ Resource Patterns:                                          │
│ - Specific resource ARN                                     │
│ - Wildcards (* for all)                                     │
│ - Resource tags (in some services)                          │
└─────────────────────────────────────────────────────────────┘

CONDITIONS (Under What Circumstances):
┌─────────────────────────────────────────────────────────────┐
│ Additional constraints on when permission applies           │
│                                                             │
│ Examples:                                                   │
│ - aws:SourceIp (request from specific IP)                   │
│ - aws:MultiFactorAuthPresent (MFA used)                     │
│ - aws:CurrentTime (time-based restrictions)                 │
│ - aws:RequestedRegion (limit to regions)                    │
│ - s3:x-amz-acl (object ACL conditions)                      │
│                                                             │
│ Use Cases:                                                  │
│ - Require MFA for sensitive actions                         │
│ - Restrict access to corporate IP ranges                    │
│ - Enforce encryption requirements                           │
│ - Time-based access windows                                 │
└─────────────────────────────────────────────────────────────┘

IAM Across Providers:

Provider IAM Comparison:

AWS IAM:
┌─────────────────────────────────────────────────────────────┐
│ Principals: Users, Groups, Roles                            │
│ Policies: JSON documents attached to principals/resources   │
│ Types:                                                      │
│ - Identity-based (attached to user/group/role)              │
│ - Resource-based (attached to resource)                     │
│ - Permission boundaries (max permissions)                   │
│ - SCPs (organization-level restrictions)                    │
│                                                             │
│ Key Features:                                               │
│ - Fine-grained permissions                                  │
│ - Cross-account roles                                       │
│ - Service-linked roles                                      │
│ - Instance profiles for EC2                                 │
└─────────────────────────────────────────────────────────────┘

Azure AD / Entra ID:
┌─────────────────────────────────────────────────────────────┐
│ Principals: Users, Groups, Service Principals, Managed IDs  │
│ Policies: RBAC roles assigned at scopes                     │
│                                                             │
│ Structure:                                                  │
│ - Tenant (directory)                                        │
│   └── Management Groups                                     │
│       └── Subscriptions                                     │
│           └── Resource Groups                               │
│               └── Resources                                 │
│                                                             │
│ Key Features:                                               │
│ - Built-in roles (Owner, Contributor, Reader)               │
│ - Custom roles                                              │
│ - Managed identities (no credential management)             │
│ - PIM (Privileged Identity Management)                      │
└─────────────────────────────────────────────────────────────┘

GCP Cloud IAM:
┌─────────────────────────────────────────────────────────────┐
│ Principals: Users, Groups, Service Accounts                 │
│ Policies: Bindings of principals to roles on resources      │
│                                                             │
│ Structure:                                                  │
│ - Organization                                              │
│   └── Folders                                               │
│       └── Projects                                          │
│           └── Resources                                     │
│                                                             │
│ Key Features:                                               │
│ - Predefined roles (curated permissions)                    │
│ - Custom roles                                              │
│ - Workload identity federation                              │
│ - IAM Conditions                                            │
└─────────────────────────────────────────────────────────────┘

Key insight: Despite different terminology, all cloud IAM systems answer the same question: who can do what to which resources under what conditions.

2) Policy Design and Least Privilege

Effective IAM requires designing policies that grant exactly the permissions needed—no more:

AWS IAM Policy Structure:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowS3ReadAccess",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::my-bucket",
                "arn:aws:s3:::my-bucket/*"
            ],
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": "192.168.1.0/24"
                }
            }
        }
    ]
}

Policy Elements:
┌─────────────────────────────────────────────────────────────┐
│ Version: Policy language version (always "2012-10-17")      │
│ Statement: Array of permission statements                   │
│ Sid: Statement identifier (optional, for documentation)     │
│ Effect: "Allow" or "Deny"                                   │
│ Action: What operations are permitted/denied                │
│ Resource: What resources the actions apply to               │
│ Condition: When the statement applies (optional)            │
└─────────────────────────────────────────────────────────────┘

Least Privilege Principles:

Implementing Least Privilege:

PRINCIPLE 1: Start with Zero Permissions
┌─────────────────────────────────────────────────────────────┐
│ Default deny—only grant what's explicitly needed            │
│                                                             │
│ Bad:  Start with admin, remove what's not needed            │
│ Good: Start with nothing, add specific permissions          │
│                                                             │
│ Process:                                                    │
│ 1. Identify specific tasks user/role must perform           │
│ 2. Determine minimum actions required                       │
│ 3. Scope to specific resources                              │
│ 4. Add conditions where possible                            │
└─────────────────────────────────────────────────────────────┘

PRINCIPLE 2: Scope Resources Narrowly
┌─────────────────────────────────────────────────────────────┐
│ Never use "*" for resources unless absolutely necessary     │
│                                                             │
│ Bad Policy:                                                 │
│ "Resource": "*"                                             │
│                                                             │
│ Good Policy:                                                │
│ "Resource": "arn:aws:s3:::app-data-bucket/*"                │
│                                                             │
│ Better Policy (with tags):                                  │
│ "Resource": "*",                                            │
│ "Condition": {                                              │
│     "StringEquals": {                                       │
│         "aws:ResourceTag/Environment": "Production"         │
│     }                                                       │
│ }                                                           │
└─────────────────────────────────────────────────────────────┘

PRINCIPLE 3: Use Conditions
┌─────────────────────────────────────────────────────────────┐
│ Add constraints beyond just action and resource             │
│                                                             │
│ Common Conditions:                                          │
│                                                             │
│ Require MFA:                                                │
│ "Condition": {                                              │
│     "Bool": {"aws:MultiFactorAuthPresent": "true"}          │
│ }                                                           │
│                                                             │
│ Restrict Source IP:                                         │
│ "Condition": {                                              │
│     "IpAddress": {"aws:SourceIp": "10.0.0.0/8"}             │
│ }                                                           │
│                                                             │
│ Require Encryption:                                         │
│ "Condition": {                                              │
│     "StringEquals": {                                       │
│         "s3:x-amz-server-side-encryption": "AES256"         │
│     }                                                       │
│ }                                                           │
└─────────────────────────────────────────────────────────────┘

PRINCIPLE 4: Separate Duties
┌─────────────────────────────────────────────────────────────┐
│ Different roles for different functions                     │
│                                                             │
│ Example Separation:                                         │
│ - Developers: Read logs, deploy to dev                      │
│ - Operators: Manage production, read configs                │
│ - Security: Read all, modify security controls              │
│ - Admins: IAM management (separate from operations)         │
│                                                             │
│ Critical Separations:                                       │
│ - IAM administration separate from resource administration  │
│ - Production access separate from development               │
│ - Audit/read access separate from write access              │
└─────────────────────────────────────────────────────────────┘

PRINCIPLE 5: Time-Bound Access
┌─────────────────────────────────────────────────────────────┐
│ Temporary permissions instead of permanent                  │
│                                                             │
│ Implementations:                                            │
│ - Assume roles instead of permanent credentials             │
│ - Just-in-time access for privileged operations             │
│ - Session-based permissions                                 │
│ - Time conditions in policies                               │
│                                                             │
│ Example Time Condition:                                     │
│ "Condition": {                                              │
│     "DateGreaterThan": {"aws:CurrentTime": "2024-01-01"},   │
│     "DateLessThan": {"aws:CurrentTime": "2024-12-31"}       │
│ }                                                           │
└─────────────────────────────────────────────────────────────┘

Policy Examples:

Real-World Policy Examples:

DEVELOPER ROLE - Read-Only Production:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ReadProductionLogs",
            "Effect": "Allow",
            "Action": [
                "logs:GetLogEvents",
                "logs:DescribeLogStreams",
                "logs:DescribeLogGroups"
            ],
            "Resource": "arn:aws:logs:*:*:log-group:/aws/prod/*"
        },
        {
            "Sid": "ReadProductionMetrics",
            "Effect": "Allow",
            "Action": [
                "cloudwatch:GetMetricData",
                "cloudwatch:ListMetrics"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/Environment": "production"
                }
            }
        }
    ]
}

APPLICATION ROLE - Specific S3 Access:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ReadAppConfig",
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::app-config-bucket/config/*"
        },
        {
            "Sid": "WriteAppData",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject"
            ],
            "Resource": "arn:aws:s3:::app-data-bucket/${aws:userid}/*"
        }
    ]
}

DENY POLICY - Prevent Region Escape:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyNonApprovedRegions",
            "Effect": "Deny",
            "Action": "*",
            "Resource": "*",
            "Condition": {
                "StringNotEquals": {
                    "aws:RequestedRegion": [
                        "us-east-1",
                        "us-west-2",
                        "eu-west-1"
                    ]
                }
            }
        }
    ]
}

Key insight: Good policies are specific, scoped, and conditional. Every wildcard (*) is a potential security hole.

3) Roles and Service Accounts

Roles enable secure access without permanent credentials—critical for services and cross-account access:

AWS IAM Roles:

ROLE COMPONENTS:
┌─────────────────────────────────────────────────────────────┐
│ Trust Policy: WHO can assume the role                       │
│ Permission Policy: WHAT the role can do                     │
│                                                             │
│ Trust Policy Example (EC2 can assume):                      │
│ {                                                           │
│     "Version": "2012-10-17",                                │
│     "Statement": [{                                         │
│         "Effect": "Allow",                                  │
│         "Principal": {                                      │
│             "Service": "ec2.amazonaws.com"                  │
│         },                                                  │
│         "Action": "sts:AssumeRole"                          │
│     }]                                                      │
│ }                                                           │
│                                                             │
│ This allows EC2 instances to assume this role               │
│ and gain its permissions                                    │
└─────────────────────────────────────────────────────────────┘

ROLE TYPES:
┌─────────────────────────────────────────────────────────────┐
│ Service Roles:                                              │
│ - Allow AWS services to act on your behalf                  │
│ - Example: Lambda execution role, EC2 instance profile      │
│                                                             │
│ Cross-Account Roles:                                        │
│ - Allow access from other AWS accounts                      │
│ - Trust policy specifies allowed account(s)                 │
│                                                             │
│ Identity Provider Roles:                                    │
│ - Allow federated users to access AWS                       │
│ - Trust policy specifies IdP                                │
│                                                             │
│ Service-Linked Roles:                                       │
│ - Pre-defined by AWS services                               │
│ - Cannot be modified, managed by service                    │
└─────────────────────────────────────────────────────────────┘

Instance Profiles and Workload Identity:

Workload Identity (No Hardcoded Credentials):

AWS - Instance Profiles:
┌─────────────────────────────────────────────────────────────┐
│ 1. Create IAM role with required permissions                │
│ 2. Attach role to EC2 instance profile                      │
│ 3. Launch instance with instance profile                    │
│ 4. Application uses SDK to get temporary credentials        │
│                                                             │
│ How it works:                                               │
│ - Instance metadata service provides credentials            │
│ - http://169.254.169.254/latest/meta-data/iam/              │
│ - Credentials automatically rotated                         │
│ - No secrets in code or config files                        │
│                                                             │
│ SDK automatically uses instance credentials:                │
│ import boto3                                                │
│ s3 = boto3.client('s3')  # Uses instance role               │
│ s3.list_buckets()        # No credentials specified         │
└─────────────────────────────────────────────────────────────┘

Azure - Managed Identities:
┌─────────────────────────────────────────────────────────────┐
│ System-Assigned:                                            │
│ - Created with and tied to specific resource                │
│ - Deleted when resource is deleted                          │
│ - One per resource                                          │
│                                                             │
│ User-Assigned:                                              │
│ - Created independently                                     │
│ - Can be shared across resources                            │
│ - Lifecycle independent of resources                        │
│                                                             │
│ Usage:                                                      │
│ from azure.identity import DefaultAzureCredential           │
│ credential = DefaultAzureCredential()  # Auto-detects       │
└─────────────────────────────────────────────────────────────┘

GCP - Service Accounts and Workload Identity:
┌─────────────────────────────────────────────────────────────┐
│ Service Accounts:                                           │
│ - Identity for compute resources                            │
│ - Attached to VMs, Cloud Functions, etc.                    │
│                                                             │
│ Workload Identity Federation:                               │
│ - External workloads assume GCP identity                    │
│ - No service account keys needed                            │
│ - Supports GitHub Actions, AWS, Azure, Kubernetes           │
│                                                             │
│ Best Practice:                                              │
│ - Never export service account keys                         │
│ - Use attached service accounts                             │
│ - Workload identity for external systems                    │
└─────────────────────────────────────────────────────────────┘

Cross-Account Access:

Cross-Account Role Assumption:

SCENARIO: Account B needs access to S3 in Account A

ACCOUNT A (Resource Owner):
┌─────────────────────────────────────────────────────────────┐
│ Create role: CrossAccountS3Access                           │
│                                                             │
│ Trust Policy (who can assume):                              │
│ {                                                           │
│     "Version": "2012-10-17",                                │
│     "Statement": [{                                         │
│         "Effect": "Allow",                                  │
│         "Principal": {                                      │
│             "AWS": "arn:aws:iam::ACCOUNT-B-ID:root"         │
│         },                                                  │
│         "Action": "sts:AssumeRole",                         │
│         "Condition": {                                      │
│             "StringEquals": {                               │
│                 "sts:ExternalId": "shared-secret-123"       │
│             }                                               │
│         }                                                   │
│     }]                                                      │
│ }                                                           │
│                                                             │
│ Permission Policy (what role can do):                       │
│ {                                                           │
│     "Version": "2012-10-17",                                │
│     "Statement": [{                                         │
│         "Effect": "Allow",                                  │
│         "Action": "s3:GetObject",                           │
│         "Resource": "arn:aws:s3:::shared-data-bucket/*"     │
│     }]                                                      │
│ }                                                           │
└─────────────────────────────────────────────────────────────┘

ACCOUNT B (Accessor):
┌─────────────────────────────────────────────────────────────┐
│ Grant permission to assume the role:                        │
│                                                             │
│ {                                                           │
│     "Version": "2012-10-17",                                │
│     "Statement": [{                                         │
│         "Effect": "Allow",                                  │
│         "Action": "sts:AssumeRole",                         │
│         "Resource": "arn:aws:iam::ACCOUNT-A-ID:role/        │
│                      CrossAccountS3Access"                  │
│     }]                                                      │
│ }                                                           │
│                                                             │
│ Usage in code:                                              │
│ sts = boto3.client('sts')                                   │
│ response = sts.assume_role(                                 │
│     RoleArn='arn:aws:iam::ACCOUNT-A:role/CrossAccountS3',   │
│     RoleSessionName='my-session',                           │
│     ExternalId='shared-secret-123'                          │
│ )                                                           │
│ # Use temporary credentials from response                   │
└─────────────────────────────────────────────────────────────┘

Key insight: Roles eliminate the need for long-lived credentials. Every workload should use roles, never access keys.

4) Identity Federation

Federation allows external identity providers to authenticate users for cloud access:

Federation Concepts:

WHY FEDERATE:
┌─────────────────────────────────────────────────────────────┐
│ Problems without federation:                                │
│ - Multiple identities to manage                             │
│ - Users forget cloud passwords                              │
│ - No central identity governance                            │
│ - Termination doesn't disable cloud access                  │
│ - No SSO experience                                         │
│                                                             │
│ Benefits of federation:                                     │
│ - Single identity source (corporate directory)              │
│ - Centralized access control                                │
│ - Immediate deprovisioning on termination                   │
│ - Consistent authentication policies                        │
│ - SSO across cloud and on-premises                          │
└─────────────────────────────────────────────────────────────┘

FEDERATION PROTOCOLS:
┌─────────────────────────────────────────────────────────────┐
│ SAML 2.0:                                                   │
│ - XML-based protocol                                        │
│ - Enterprise standard                                       │
│ - Browser-based SSO                                         │
│ - IdP sends signed assertion to cloud                       │
│                                                             │
│ OIDC (OpenID Connect):                                      │
│ - JSON/JWT-based                                            │
│ - Modern, mobile-friendly                                   │
│ - Built on OAuth 2.0                                        │
│ - Used by social providers, Okta, Azure AD                  │
│                                                             │
│ Custom Federation (AWS):                                    │
│ - AssumeRoleWithWebIdentity                                 │
│ - Direct integration with IdP                               │
└─────────────────────────────────────────────────────────────┘

SAML FLOW:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   User         Corporate IdP        AWS                     │
│    │                │                │                      │
│    │─── Login ─────►│                │                      │
│    │                │                │                      │
│    │◄── SAML ──────│                │                      │
│    │    Assertion   │                │                      │
│    │                │                │                      │
│    │────── POST Assertion ──────────►│                      │
│    │                │                │                      │
│    │◄───── Temporary Credentials ────│                      │
│    │                │                │                      │
│                                                             │
└─────────────────────────────────────────────────────────────┘

AWS Federation Options:

AWS Identity Federation:

AWS IAM IDENTITY CENTER (SSO):
┌─────────────────────────────────────────────────────────────┐
│ Recommended approach for workforce identity                 │
│                                                             │
│ Features:                                                   │
│ - Central portal for all AWS accounts                       │
│ - Permission sets define access                             │
│ - Integrates with external IdPs                             │
│ - Built-in user directory option                            │
│                                                             │
│ Flow:                                                       │
│ 1. User logs into SSO portal                                │
│ 2. Authenticates via IdP (Okta, Azure AD, etc.)             │
│ 3. Selects account and permission set                       │
│ 4. Gets temporary credentials                               │
│ 5. Accesses AWS console or CLI                              │
└─────────────────────────────────────────────────────────────┘

SAML 2.0 FEDERATION (Direct):
┌─────────────────────────────────────────────────────────────┐
│ Direct federation between IdP and AWS                       │
│                                                             │
│ Setup:                                                      │
│ 1. Create SAML identity provider in IAM                     │
│ 2. Upload IdP metadata                                      │
│ 3. Create IAM role trusting the IdP                         │
│ 4. Configure IdP to send appropriate attributes             │
│                                                             │
│ Trust Policy for SAML Role:                                 │
│ {                                                           │
│     "Version": "2012-10-17",                                │
│     "Statement": [{                                         │
│         "Effect": "Allow",                                  │
│         "Principal": {                                      │
│             "Federated":                                    │
│               "arn:aws:iam::123456789:saml-provider/Okta"   │
│         },                                                  │
│         "Action": "sts:AssumeRoleWithSAML",                 │
│         "Condition": {                                      │
│             "StringEquals": {                               │
│                 "SAML:aud":                                 │
│                   "https://signin.aws.amazon.com/saml"      │
│             }                                               │
│         }                                                   │
│     }]                                                      │
│ }                                                           │
└─────────────────────────────────────────────────────────────┘

WEB IDENTITY FEDERATION:
┌─────────────────────────────────────────────────────────────┐
│ For applications authenticating users via social/OIDC       │
│                                                             │
│ Use Cases:                                                  │
│ - Mobile apps with Cognito                                  │
│ - GitHub Actions deploying to AWS                           │
│ - Kubernetes pods accessing AWS                             │
│                                                             │
│ GitHub Actions Example:                                     │
│ Trust Policy:                                               │
│ {                                                           │
│     "Principal": {                                          │
│         "Federated":                                        │
│           "arn:aws:iam::123456789:oidc-provider/            │
│            token.actions.githubusercontent.com"              │
│     },                                                      │
│     "Condition": {                                          │
│         "StringEquals": {                                   │
│             "token.actions.githubusercontent.com:aud":      │
│               "sts.amazonaws.com"                           │
│         },                                                  │
│         "StringLike": {                                     │
│             "token.actions.githubusercontent.com:sub":      │
│               "repo:myorg/myrepo:*"                         │
│         }                                                   │
│     }                                                       │
│ }                                                           │
└─────────────────────────────────────────────────────────────┘

Azure AD Federation:

Azure AD as Identity Platform:

AZURE AD CONCEPTS:
┌─────────────────────────────────────────────────────────────┐
│ Tenant: Directory instance (organization)                   │
│ Application: Registered app that can request tokens         │
│ Service Principal: App's identity in a tenant               │
│ Managed Identity: Azure-managed service principal           │
│                                                             │
│ Authentication:                                             │
│ - Users authenticate to Azure AD                            │
│ - Azure AD issues tokens                                    │
│ - Tokens grant access to Azure resources                    │
│ - Tokens can grant access to other clouds (federation)      │
└─────────────────────────────────────────────────────────────┘

CONDITIONAL ACCESS:
┌─────────────────────────────────────────────────────────────┐
│ Policy-based access control beyond simple authentication    │
│                                                             │
│ Signals:                                                    │
│ - User/group membership                                     │
│ - Device state (compliant, hybrid joined)                   │
│ - Location (IP, country)                                    │
│ - Application being accessed                                │
│ - Risk level (Azure AD Identity Protection)                 │
│                                                             │
│ Controls:                                                   │
│ - Block access                                              │
│ - Require MFA                                               │
│ - Require compliant device                                  │
│ - Require password change                                   │
│ - Session controls                                          │
│                                                             │
│ Example Policy:                                             │
│ IF user is accessing Azure Portal                           │
│ AND user is outside corporate network                       │
│ AND device is not compliant                                 │
│ THEN require MFA                                            │
└─────────────────────────────────────────────────────────────┘

Key insight: Federation centralizes identity management while enabling cloud access—eliminating orphan accounts and password sprawl.

5) IAM Security Best Practices and Common Vulnerabilities

IAM misconfigurations are the leading cause of cloud security incidents:

Common IAM Vulnerabilities:

OVERLY PERMISSIVE POLICIES:
┌─────────────────────────────────────────────────────────────┐
│ Problem: Using "*" for actions or resources                 │
│                                                             │
│ Dangerous Patterns:                                         │
│ "Action": "*"                     # Admin to everything     │
│ "Action": "s3:*"                  # Full S3 access          │
│ "Resource": "*"                   # All resources           │
│ "Action": "iam:*"                 # IAM admin               │
│                                                             │
│ Real Example:                                               │
│ Developer given "PowerUser" access                          │
│ - Can't manage IAM directly                                 │
│ - CAN create Lambda with admin role                         │
│ - Privilege escalation achieved                             │
│                                                             │
│ Fix: Specific actions on specific resources                 │
└─────────────────────────────────────────────────────────────┘

EXPOSED ACCESS KEYS:
┌─────────────────────────────────────────────────────────────┐
│ Problem: Hardcoded or leaked credentials                    │
│                                                             │
│ Common Exposure Points:                                     │
│ - Source code repositories (GitHub)                         │
│ - Configuration files                                       │
│ - Environment variables in logs                             │
│ - Container images                                          │
│ - Client-side code                                          │
│                                                             │
│ Attacker Actions:                                           │
│ - Automated scanning of GitHub for AWS keys                 │
│ - Keys compromised within minutes of commit                 │
│ - Immediate cryptomining or data theft                      │
│                                                             │
│ Fix:                                                        │
│ - Use roles instead of access keys                          │
│ - Secrets managers for necessary credentials                │
│ - Git hooks to prevent committing secrets                   │
│ - Regular key rotation                                      │
└─────────────────────────────────────────────────────────────┘

PRIVILEGE ESCALATION PATHS:
┌─────────────────────────────────────────────────────────────┐
│ Problem: Permissions that allow gaining more permissions    │
│                                                             │
│ Escalation Techniques:                                      │
│                                                             │
│ 1. iam:CreatePolicyVersion                                  │
│    - Modify managed policy to add permissions               │
│                                                             │
│ 2. iam:AttachUserPolicy / AttachRolePolicy                  │
│    - Attach admin policy to self                            │
│                                                             │
│ 3. iam:PassRole + service:Create*                           │
│    - Create resource with privileged role                   │
│    - Lambda, EC2, Glue, etc.                                │
│                                                             │
│ 4. sts:AssumeRole on privileged role                        │
│    - Directly assume more privileged role                   │
│                                                             │
│ 5. iam:UpdateLoginProfile                                   │
│    - Change another user's password                         │
│                                                             │
│ Fix: Audit for these permissions, use permission boundaries │
└─────────────────────────────────────────────────────────────┘

MISSING MFA:
┌─────────────────────────────────────────────────────────────┐
│ Problem: Sensitive actions without MFA requirement          │
│                                                             │
│ Risk: Stolen password = full access                         │
│                                                             │
│ Where MFA Should Be Required:                               │
│ - Console login                                             │
│ - Sensitive API actions                                     │
│ - Production environment access                             │
│ - IAM changes                                               │
│ - Billing access                                            │
│                                                             │
│ MFA Condition in Policy:                                    │
│ "Condition": {                                              │
│     "Bool": {                                               │
│         "aws:MultiFactorAuthPresent": "true"                │
│     }                                                       │
│ }                                                           │
└─────────────────────────────────────────────────────────────┘

ROOT ACCOUNT MISUSE:
┌─────────────────────────────────────────────────────────────┐
│ Problem: Using root account for daily operations            │
│                                                             │
│ Risks:                                                      │
│ - Root cannot be restricted                                 │
│ - Root compromise = total account compromise                │
│ - No audit trail attribution                                │
│                                                             │
│ Fix:                                                        │
│ - Enable MFA on root (hardware key recommended)             │
│ - Never create root access keys                             │
│ - Use root only for tasks that require it                   │
│ - Create IAM admin users for administration                 │
│ - Alert on any root account usage                           │
└─────────────────────────────────────────────────────────────┘

IAM Security Best Practices:

IAM Security Checklist:

IDENTITY MANAGEMENT:
□ MFA enabled on all human users
□ Hardware MFA on root and admins
□ No shared accounts or credentials
□ Regular access reviews
□ Immediate deprovisioning on termination
□ Federation for workforce identity

CREDENTIAL MANAGEMENT:
□ No long-lived access keys for humans
□ Roles used for all workloads
□ Secrets in secrets manager, not code
□ Regular credential rotation
□ Alerts on credential exposure

PERMISSION MANAGEMENT:
□ Least privilege policies
□ No wildcard actions or resources
□ Permission boundaries on roles
□ Regular permission audits
□ Service Control Policies at org level
□ No inline policies (use managed)

MONITORING:
□ CloudTrail enabled all regions
□ Alert on IAM changes
□ Alert on root account usage
□ Alert on failed authentication
□ Regular access analyzer reviews

GOVERNANCE:
□ Tagging policy for resources
□ Naming conventions for IAM entities
□ Policy review process
□ Change management for IAM
□ Documentation of access patterns

Tools for IAM Security:

IAM Security Analysis Tools:

AWS NATIVE:
┌─────────────────────────────────────────────────────────────┐
│ IAM Access Analyzer:                                        │
│ - Identifies resources shared externally                    │
│ - Validates policies against best practices                 │
│ - Generates least-privilege policies                        │
│                                                             │
│ IAM Policy Simulator:                                       │
│ - Test policies before applying                             │
│ - Understand effective permissions                          │
│                                                             │
│ AWS Config Rules:                                           │
│ - iam-password-policy                                       │
│ - iam-root-access-key-check                                 │
│ - mfa-enabled-for-iam-console-access                        │
└─────────────────────────────────────────────────────────────┘

OPEN SOURCE:
┌─────────────────────────────────────────────────────────────┐
│ Prowler:                                                    │
│ - Comprehensive AWS security assessment                     │
│ - IAM-focused checks                                        │
│                                                             │
│ ScoutSuite:                                                 │
│ - Multi-cloud security auditing                             │
│ - IAM configuration analysis                                │
│                                                             │
│ Cloudsplaining:                                             │
│ - IAM policy analysis                                       │
│ - Privilege escalation detection                            │
│                                                             │
│ PMapper (Principal Mapper):                                 │
│ - Maps IAM privilege escalation paths                       │
│ - Visualizes trust relationships                            │
│                                                             │
│ IAM Vulnerable:                                             │
│ - Creates intentionally vulnerable IAM for practice         │
└─────────────────────────────────────────────────────────────┘

Key insight: Assume every IAM misconfiguration will be found and exploited. Regular auditing and automated enforcement are essential.

Real-World Context

Case Study: Capital One IAM Exploitation

The 2019 Capital One breach centered on IAM misconfiguration. An attacker exploited an SSRF vulnerability to access the EC2 metadata service and retrieve credentials for an IAM role attached to the instance. The role had excessive permissions— including the ability to list and read S3 buckets across the account. Proper least privilege would have limited the role to only the specific buckets and operations the application needed. Additionally, the role could have been scoped to specific source VPCs or required additional authentication for sensitive operations.

Case Study: GitHub Actions OIDC Federation

Organizations traditionally stored AWS access keys in GitHub secrets for CI/CD pipelines. These long-lived credentials were frequently exposed through repository misconfigurations or insider threats. AWS IAM's OIDC federation capability transformed this pattern: GitHub Actions can now assume AWS roles directly using short-lived tokens. No secrets stored, credentials automatically expire after the workflow, and access can be scoped to specific repositories and branches. This demonstrates how proper IAM architecture eliminates entire classes of vulnerabilities.

IAM Anti-Patterns to Avoid:

Common IAM Mistakes:

MISTAKE: "Just use admin for now, we'll fix later"
┌─────────────────────────────────────────────────────────────┐
│ Reality: "Later" never comes, admin persists                │
│ Risk: Any compromise has full account access                │
│ Fix: Start with least privilege from day one                │
└─────────────────────────────────────────────────────────────┘

MISTAKE: One role for all environments
┌─────────────────────────────────────────────────────────────┐
│ Reality: Dev workload can affect production                 │
│ Risk: Dev compromise = production compromise                │
│ Fix: Separate roles per environment with boundaries         │
└─────────────────────────────────────────────────────────────┘

MISTAKE: Access keys instead of roles
┌─────────────────────────────────────────────────────────────┐
│ Reality: Keys get committed, shared, forgotten              │
│ Risk: Long-lived credentials with no expiration             │
│ Fix: Roles with temporary credentials everywhere            │
└─────────────────────────────────────────────────────────────┘

MISTAKE: No MFA because "it's inconvenient"
┌─────────────────────────────────────────────────────────────┐
│ Reality: Password alone = trivial to compromise             │
│ Risk: Phishing, credential stuffing succeed                 │
│ Fix: MFA required for all human access                      │
└─────────────────────────────────────────────────────────────┘

MISTAKE: Not reviewing access after role changes
┌─────────────────────────────────────────────────────────────┐
│ Reality: Former responsibilities retain access              │
│ Risk: Privilege accumulation over time                      │
│ Fix: Regular access reviews, automated cleanup              │
└─────────────────────────────────────────────────────────────┘

IAM is the foundation of cloud security. Every other control depends on IAM being correctly configured.

Guided Lab: IAM Policy Design and Analysis

In this lab, you'll design least-privilege policies and analyze existing policies for vulnerabilities.

Lab Environment:

  • AWS account with IAM access
  • IAM Policy Simulator
  • Sample application requirements

Exercise Steps:

  1. Create IAM user with MFA
  2. Design policy for specific application needs
  3. Test policy using IAM Policy Simulator
  4. Create role for EC2 with instance profile
  5. Analyze provided overprivileged policy
  6. Identify privilege escalation paths
  7. Remediate policy to least privilege
  8. Document policy decisions

Reflection Questions:

  • How did you determine the minimum required permissions?
  • What privilege escalation paths did you identify?
  • How would you monitor for IAM policy drift?

Week Outcome Check

By the end of this week, you should be able to:

  • Explain IAM concepts: principals, actions, resources, conditions
  • Compare IAM implementations across AWS, Azure, and GCP
  • Design least-privilege IAM policies
  • Implement roles for workloads instead of access keys
  • Configure identity federation with external IdPs
  • Identify common IAM vulnerabilities and privilege escalation paths
  • Apply IAM security best practices
  • Use IAM analysis tools to audit configurations

🎯 Hands-On Labs (Free & Essential)

Master IAM through hands-on practice—the single most critical cloud security skill.

🔐 TryHackMe: AWS IAM Privilege Escalation

What you'll do: Exploit misconfigured IAM policies to escalate privileges and understand common attack vectors.
Why it matters: Learning attacker techniques helps you defend against real IAM exploitation.
Time estimate: 2-3 hours

Start IAM Privilege Escalation →

🛡️ AWS Skill Builder: IAM Policy Design

What you'll do: Complete IAM policy fundamentals lab—create least-privilege policies and test with Policy Simulator.
Why it matters: Properly designed policies prevent 90% of IAM-related breaches.
Time estimate: 2-3 hours

Open AWS IAM Training →

🧪 HackTheBox Academy: Cloud IAM Exploitation

What you'll do: Practice identifying and exploiting IAM misconfigurations in realistic scenarios (free tier modules).
Why it matters: Hands-on exploitation experience is invaluable for defensive security.
Time estimate: 2-4 hours

Open HTB Academy →

💡 Lab Strategy: Start with AWS Skill Builder for policy design fundamentals, then practice exploitation on TryHackMe and HTB to understand attacker perspectives.

Resources

Lab

Complete the following lab exercises to practice cloud IAM security.

Part 1: User and MFA Setup (LO2)

Create secure IAM users: (a) create admin user without using root, (b) enable MFA, (c) create policy requiring MFA for sensitive operations, (d) test MFA enforcement.

Deliverable: Documentation of user setup with MFA policy and test results.

Part 2: Least Privilege Policy Design (LO2)

Design policies for an application that needs to: (a) read from specific S3 bucket, (b) write to specific DynamoDB table, (c) publish to specific SNS topic. Create minimal policy covering only these requirements.

Deliverable: JSON policy document with explanation of each permission.

Part 3: Role Configuration (LO2)

Create and configure IAM roles: (a) EC2 instance role with instance profile, (b) Lambda execution role, (c) cross-account role for specific access. Test each role functions correctly.

Deliverable: Role configurations with trust policies and permission policies documented.

Part 4: Policy Analysis (LO2)

Analyze provided overprivileged policies: (a) identify excessive permissions, (b) find privilege escalation paths, (c) create remediated least-privilege versions, (d) test with policy simulator.

Deliverable: Analysis report with original vs. remediated policies and risk assessment.

Part 5: IAM Security Audit (LO2)

Conduct IAM security audit: (a) run Prowler or Scout Suite, (b) identify IAM findings, (c) prioritize by risk, (d) create remediation plan for top 5 findings.

Deliverable: Audit report with findings, risk ratings, and remediation recommendations.

Checkpoint Questions

  1. Explain the components of an IAM policy: principals, actions, resources, and conditions. Give examples of each.
  2. What is the principle of least privilege? How do you implement it in cloud IAM?
  3. Why should workloads use roles instead of access keys? What are instance profiles and managed identities?
  4. What is identity federation? How does SAML federation work with AWS?
  5. Describe three privilege escalation paths in AWS IAM. How would you detect and prevent them?
  6. What IAM configurations should trigger security alerts? How would you implement this monitoring?

Week 02 Quiz

Test your understanding of Identity & Access Management (IAM).

Format: 10 multiple-choice questions. Passing score: 70%. Time: Untimed.

Take Quiz

Weekly Reflection

IAM is often called the most important cloud security control because every other security measure depends on it. This week explored how to implement IAM securely.

Reflect on the following in 200-300 words:

A strong reflection demonstrates understanding of IAM as the foundation of cloud security and the challenges of implementing least privilege at scale.

Verified Resources & Videos

← Previous: Week 01 Next: Week 03 →