Introduction: Why IAM Is Your AWS Security Foundation
AWS Identity and Access Management (IAM) is the control system for your entire AWS infrastructure, governing who can access what resources and how. Proper IAM configuration is critical for security, compliance, and operational efficiency. IAM operates on the principle of least privilege, ensuring users and services have only the permissions they need to perform their tasks.
Core IAM Concepts & Components
| Component | Description | Use Case |
|---|
| User | Identity for individuals requiring AWS access | Developers, administrators, applications |
| Group | Collection of IAM users | Organize users by function (admins, developers) |
| Role | Identity with permissions that can be assumed | Cross-account access, EC2 instance profiles |
| Policy | Document defining permissions | Control access to AWS services and resources |
| Permission Boundary | Sets maximum permissions for an identity | Delegate permissions without escalation risk |
| Resource-based Policy | Policy attached directly to a resource | S3 bucket policies, SQS queue policies |
| Service Control Policy (SCP) | Policy that limits permissions in an organization | Enforce compliance across accounts |
| Identity Provider (IdP) | External system for authentication | Integrate with corporate directories |
IAM Users: Individual Identities
User Creation Best Practices
- Create individual IAM users (not shared accounts)
- Enforce strong password policies
- Enable MFA for all users, especially those with privileged access
- Use Access Keys only when necessary, rotate regularly
- Assign users to groups for permissions management
User Access Types
| Access Type | Use Case | Best Practice |
|---|
| Console Access | Management via AWS console | Use SSO when possible, enable MFA |
| Programmatic Access | API, CLI, SDK access | Use temporary credentials, store securely |
| Access Keys | Long-term API credentials | Rotate regularly (90 days), never embed in code |
| SSH Keys | EC2 instance access | Manage centrally, rotate regularly |
User Management Commands
# Create a new user
aws iam create-user --user-name alice
# Add user to group
aws iam add-user-to-group --user-name alice --group-name developers
# Create access key for programmatic access
aws iam create-access-key --user-name alice
# Enable MFA for a user
aws iam enable-mfa-device --user-name alice --serial-number arn:aws:iam::123456789012:mfa/alice --authentication-code1 123456 --authentication-code2 789012
# List user's policies
aws iam list-attached-user-policies --user-name alice
IAM Groups: Organizing Users
Common Group Structures
| Group Type | Purpose | Example Permissions |
|---|
| Administrator | Full access accounts | AdministratorAccess policy |
| Power User | Admin access without user/group management | PowerUserAccess policy |
| Developer | Deploy and manage specific services | Custom policy for EC2, S3, RDS, etc. |
| ReadOnly | Monitoring and auditing | ReadOnlyAccess policy |
| Billing | Finance team access | Billing and cost management |
| Security | Security operations | SecurityAudit policy |
Group Management Commands
# Create a new group
aws iam create-group --group-name developers
# Attach policy to group
aws iam attach-group-policy --group-name developers --policy-arn arn:aws:iam::aws:policy/AmazonEC2FullAccess
# List groups for user
aws iam list-groups-for-user --user-name alice
# Remove user from group
aws iam remove-user-from-group --user-name alice --group-name developers
# Delete group (must remove all users and detach all policies first)
aws iam delete-group --group-name developers
IAM Roles: Temporary Credentials
Role Types & Use Cases
| Role Type | Use Case | Example |
|---|
| Service Role | Allow AWS service to act on your behalf | Lambda execution role |
| Cross-Account Role | Access resources in another account | Multi-account environments |
| Identity Provider Role | Federation with external IdPs | SAML/OIDC federation |
| EC2 Instance Profile | Grant EC2 instances access to AWS resources | Application on EC2 accessing S3 |
| Service-Linked Role | Predefined by AWS services | Managed service integrations |
Role Trust Relationships
Trust policies determine which entities can assume a role:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Common Role Patterns
| Pattern | Description | Benefits |
|---|
| EC2 Instance Profiles | Attach roles to EC2 instances | No hard-coded credentials |
| Cross-Account Access | Access resources across accounts | Simplified multi-account management |
| Federation | External identity integration | Single sign-on experience |
| Application Roles | Service-specific permissions | Least privilege for applications |
Role Management Commands
# Create a role
aws iam create-role --role-name s3-read-only --assume-role-policy-document file://trust-policy.json
# Attach policy to role
aws iam attach-role-policy --role-name s3-read-only --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
# List roles
aws iam list-roles
# Get role
aws iam get-role --role-name s3-read-only
# Delete role
aws iam delete-role --role-name s3-read-only
IAM Policies: Permission Definitions
Policy Types
| Policy Type | Description | Use Case |
|---|
| AWS Managed | Created and managed by AWS | Common permissions sets |
| Customer Managed | Created and managed by you | Organization-specific permissions |
| Inline | Embedded directly in user, group, or role | One-off permissions |
| Identity-Based | Attached to IAM identities | What actions identities can perform |
| Resource-Based | Attached to resources | Who can access specific resources |
| Permission Boundaries | Maximum permissions for an identity | Delegate admin without privilege escalation |
| Service Control Policies | Maximum permissions within an organization | Enforce organizational compliance |
Policy Structure
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::example-bucket",
"arn:aws:s3:::example-bucket/*"
],
"Condition": {
"IpAddress": {
"aws:SourceIp": "203.0.113.0/24"
}
}
}
]
}
Policy Elements
| Element | Description | Example |
|---|
| Version | Policy language version | “2012-10-17” |
| Statement | Array of permission statements | Individual permissions |
| Effect | Whether to allow or deny | “Allow” or “Deny” |
| Action | API actions to allow/deny | “s3:GetObject” |
| Resource | Resources affected by actions | “arn:aws:s3:::bucket-name” |
| Condition | Conditions for when policy applies | IP restrictions, time-of-day |
| Principal | Entity that gets permissions (resource policies) | AWS account, IAM user, role |
| NotAction/NotResource | Exceptions to actions/resources | All except specified |
Policy Evaluation Logic
- Explicit deny takes precedence over any allows
- If no explicit allow, default is deny
- Multiple policy types are evaluated together:
- Identity-based policies
- Resource-based policies
- SCPs (Organizations)
- Permission boundaries
- Session policies
Policy Management Commands
# Create policy
aws iam create-policy --policy-name custom-s3-policy --policy-document file://policy.json
# Get policy
aws iam get-policy --policy-arn arn:aws:iam::123456789012:policy/custom-s3-policy
# List policies
aws iam list-policies --only-attached
# Attach policy to user
aws iam attach-user-policy --user-name alice --policy-arn arn:aws:iam::123456789012:policy/custom-s3-policy
# Detach policy from user
aws iam detach-user-policy --user-name alice --policy-arn arn:aws:iam::123456789012:policy/custom-s3-policy
# Delete policy
aws iam delete-policy --policy-arn arn:aws:iam::123456789012:policy/custom-s3-policy
IAM Security Best Practices
Authentication Controls
| Control | Implementation | Benefit |
|---|
| MFA | Virtual MFA, U2F keys, hardware tokens | Prevents unauthorized access even if credentials are compromised |
| Password Policy | Minimum length, complexity, rotation | Reduces risk of brute force attacks |
| Access Keys | Rotate regularly, audit usage | Minimizes impact of leaked credentials |
| Temporary Credentials | Use STS for short-term access | Reduces risk window |
MFA Implementation
| MFA Type | Pros | Cons |
|---|
| Virtual MFA | Free, easy to set up | Vulnerable to phone compromise |
| U2F Security Keys | Hardware-based, phishing-resistant | Additional cost, physical device |
| Hardware MFA Token | No dependency on phone | Additional cost, physical device |
Least Privilege Implementation
- Start with minimum permissions, add as needed
- Analyze access with IAM Access Analyzer
- Use permission boundaries for delegation
- Grant temporary permissions for specific tasks
- Regularly review and remove unused permissions
- Implement SCPs for organization-wide controls
Common Security Policies
| Policy | Purpose | Implementation |
|---|
| Enforce MFA | Require MFA for all actions | Condition: aws:MultiFactorAuthPresent |
| Restrict by IP | Allow access only from corporate IPs | Condition: aws:SourceIp |
| Time-based access | Allow access only during business hours | Condition: aws:CurrentTime |
| Resource tagging enforcement | Require specific tags on resources | Condition: aws:RequestTag |
| Service control | Deny access to specific services | Action: service:* with “Deny” |
IAM Security Auditing
Key Auditing Tools
| Tool | Purpose | Use Case |
|---|
| IAM Access Analyzer | Identify resources shared outside intended boundary | Detect unintended public/cross-account access |
| IAM Access Advisor | Show service permissions used by a principal | Right-sizing permissions |
| CloudTrail | Track all API activities | Audit user actions and policy changes |
| AWS Config | Monitor resource configurations | Track IAM policy compliance |
| Credential Report | Download report of all users and credential status | Audit credential usage and rotation |
Key Auditing Commands
# Generate credential report
aws iam generate-credential-report
# Get credential report
aws iam get-credential-report
# List access keys older than 90 days
aws iam list-access-keys --user-name alice --query 'AccessKeyMetadata[?CreateDate<=`2024-02-08`]'
# Get service last accessed information
aws iam get-service-last-accessed-details --arn arn:aws:iam::123456789012:user/alice
Cross-Account Access Patterns
Cross-Account Role Setup
- Create role in target account with trusted principal being source account
- Attach policies to role for necessary permissions
- Update trust policy to allow specific users/roles in source account
- Grant source account users permission to assume the role
// Trust policy in target account
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::SOURCE-ACCOUNT-ID:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"aws:PrincipalOrgID": "o-xxxxxxxxxx"
}
}
}
]
}
// Policy in source account to allow assuming role
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::TARGET-ACCOUNT-ID:role/CrossAccountRole"
}
]
}
Assuming Cross-Account Roles
# Assume role and get temporary credentials
aws sts assume-role --role-arn arn:aws:iam::TARGET-ACCOUNT-ID:role/CrossAccountRole --role-session-name cross-account-session
# Set temporary credentials in profile
aws configure set aws_access_key_id ASIA1234567890EXAMPLE --profile cross-account
aws configure set aws_secret_access_key wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY --profile cross-account
aws configure set aws_session_token IQoJb3JpZ2luX2VjEP3//////////wEaCXVzLWVhc3QtMSJHMEUCIQDWEwGSr4QpQgRLirXcSAGKsEWAM5buy45awWcr+mYRoAIgNhXvtf6bGBTyLnFPY1tQQXMO4jPO1qKt3HEp7MRxrx8q2wMImf//////////ARAAGgw5NzU0MjYyNzY5NzAiDMoiEXampMnLQpMbmCq3A36%21EXAMPLE --profile cross-account
aws configure set region us-east-1 --profile cross-account
# Use the assumed role
aws s3 ls --profile cross-account
Federation with External Identity Providers
Federation Types
| Type | Use Case | Implementation |
|---|
| SAML 2.0 | Enterprise directory integration (AD) | AWS SSO, third-party IdP |
| OIDC | Web identity providers (Google, Facebook) | Web Identity Federation |
| AWS SSO | Unified access to multiple accounts | AWS Organizations integration |
| Custom Identity Broker | Complex federation requirements | Custom solution with STS |
SAML 2.0 Federation Flow
- User authenticates to corporate IdP
- IdP sends SAML assertion to user’s browser
- Browser POSTs assertion to AWS SAML endpoint
- AWS STS returns temporary credentials
- User accesses AWS resources with temporary credentials
OIDC Federation Flow
- App authenticates user with web IdP (Google, Facebook)
- App receives token from IdP
- App calls AssumeRoleWithWebIdentity with token
- AWS STS verifies token and returns temporary credentials
- App uses credentials to access AWS resources
Troubleshooting IAM Issues
Common Access Issues
| Issue | Possible Causes | Solutions |
|---|
| Access Denied | Insufficient permissions, explicit deny | Check policies, SCPs, resource policies |
| Invalid credentials | Expired/incorrect access keys | Verify/rotate access keys |
| MFA required | MFA enforcement policy in effect | Enable and use MFA |
| Policy validation error | Syntax issues in policy | Use policy validator |
| Resource not found | Region mismatch, incorrect ARN | Verify resource exists and ARN is correct |
Troubleshooting Steps
- Check explicit denies in all applicable policies
- Verify resource ARNs are correct and resources exist
- Review conditions in policies that might be restricting access
- Check resource-based policies (S3, SQS, etc.)
- Validate service control policies if using Organizations
- Verify permission boundaries if applied
- Check session policies if using temporary credentials
- Review IAM policy simulator results
- Analyze CloudTrail logs for detailed error messages
Policy Debugging Tools
| Tool | Purpose |
|---|
| IAM Policy Simulator | Test policies without making API calls |
| CloudTrail | Review detailed access denial events |
| Access Analyzer | Find unintended resource access |
| AWS Config | Track IAM policy changes |
Common IAM Tasks: Command Reference
User Management
# Create user
aws iam create-user --user-name bob
# Create login profile (console access)
aws iam create-login-profile --user-name bob --password P@ssw0rd --password-reset-required
# Update user's password
aws iam update-login-profile --user-name bob --password NewP@ssw0rd
# Delete login profile
aws iam delete-login-profile --user-name bob
# Delete user
aws iam delete-user --user-name bob
Group Management
# Create group
aws iam create-group --group-name ProjectA
# Add user to group
aws iam add-user-to-group --group-name ProjectA --user-name bob
# List groups
aws iam list-groups
# List users in group
aws iam get-group --group-name ProjectA
# Remove user from group
aws iam remove-user-from-group --group-name ProjectA --user-name bob
# Delete group
aws iam delete-group --group-name ProjectA
Role Management
# Create role with trust policy
aws iam create-role --role-name lambda-execution --assume-role-policy-document file://trust-policy.json
# List roles
aws iam list-roles
# Get role
aws iam get-role --role-name lambda-execution
# Delete role
aws iam delete-role --role-name lambda-execution
Policy Management
# Create customer managed policy
aws iam create-policy --policy-name custom-policy --policy-document file://policy.json
# List policies
aws iam list-policies --scope Local
# Get policy
aws iam get-policy --policy-arn arn:aws:iam::123456789012:policy/custom-policy
# Get policy document (version)
aws iam get-policy-version --policy-arn arn:aws:iam::123456789012:policy/custom-policy --version-id v1
# Delete policy
aws iam delete-policy --policy-arn arn:aws:iam::123456789012:policy/custom-policy
Access Key Management
# Create access key
aws iam create-access-key --user-name bob
# List access keys
aws iam list-access-keys --user-name bob
# Update access key status
aws iam update-access-key --user-name bob --access-key-id AKIAIOSFODNN7EXAMPLE --status Inactive
# Delete access key
aws iam delete-access-key --user-name bob --access-key-id AKIAIOSFODNN7EXAMPLE
Resources for Further Learning
AWS Official Documentation
AWS Whitepapers
AWS Training