TL;DR
A comprehensive guide to understanding AWS IAM concepts, policies, and best practices for secure access management in your AWS infrastructure.
An Overview of AWS Identity and Access Management (IAM)
AWS Identity and Access Management (IAM) is a fundamental service that enables you to manage access to AWS services and resources securely. It provides fine-grained access control across all of AWS, allowing you to specify who can access which resources and under what conditions. IAM is crucial for implementing the principle of least privilege, ensuring that users and applications have only the permissions they need to perform their tasks.
`` flowchart TB
A[Root Account] --> B[IAM Users]
A --> C[IAM Groups]
A --> D[IAM Roles]
B --> E[Permissions]
C --> E
D --> E
E --> F[AWS Resources]
style A fill:#f96,stroke:#333,stroke-width:2px
style E fill:#bbf,stroke:#333,stroke-width:2px
mermaid
`
$1
$1
IAM Users represent individual entities that need access to your AWS resources. Here's an example of creating an IAM user and group using CloudFormation:
` Resources:
DevelopersGroup:
Type: 'AWS::IAM::Group'
Properties:
GroupName: Developers
ManagedPolicyArns:
- arn:aws:iam::aws:policy/PowerUserAccess
Developer:
Type: 'AWS::IAM::User'
Properties:
UserName: john.doe
Groups:
- !Ref DevelopersGroup
LoginProfile:
Password: !Ref 'UserPassword'
PasswordResetRequired: true
AccessKey:
Type: 'AWS::IAM::AccessKey'
Properties:
UserName: !Ref Developer
yaml
`
$1
| User Type | Description | Common Permissions |
|---|---|---|
| Administrator | Full access to all resources | Admin policy |
| Developer | Access to development resources | PowerUser policy |
| Security Auditor | Read-only access for auditing | Security Audit policy |
| Application User | Limited access for specific apps | Custom scoped policy |
| Database Admin | Access to database services | Database admin policy |
$1
IAM Roles architecture and trust relationships:
` graph LR
A[Principal] -->|Assumes| B[IAM Role]
B -->|Temporary Credentials| C[STS]
B -->|Grants| D[Permissions]
D -->|Access| E[AWS Services]
subgraph Trust Policy
B
C
end
subgraph Permission Policy
D
E
end
mermaid
`
Example of a service role for EC2:
` Resources:
EC2ServiceRole:
Type: 'AWS::IAM::Role'
Properties:
RoleName: EC2ServiceRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: ec2.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
- arn:aws:iam::aws:policy/AmazonRDSReadOnlyAccess
yaml
`
$1
$1
Policy evaluation flow:
` flowchart TB
A[Request] --> B{Explicit Deny?}
B -->|Yes| C[Deny Access]
B -->|No| D{Explicit Allow?}
D -->|Yes| E[Allow Access]
D -->|No| F[Deny Access]
style C fill:#f96,stroke:#333,stroke-width:2px
style E fill:#9f6,stroke:#333,stroke-width:2px
mermaid
`
Example of a custom policy with conditions:
` {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowEC2ManagementInRegion",
"Effect": "Allow",
"Action": [
"ec2:RunInstances",
"ec2:StartInstances",
"ec2:StopInstances"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:RequestedRegion": ["us-east-1", "eu-west-1"]
},
"StringLike": {
"ec2:InstanceType": ["t2.", "t3."]
}
}
}
]
}
json
`
$1
Example S3 bucket policy with cross-account access:
` Resources:
SharedBucket:
Type: 'AWS::S3::Bucket'
Properties:
BucketName: shared-resources-bucket
BucketPolicy:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref SharedBucket
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: AllowCrossAccountAccess
Effect: Allow
Principal:
AWS: 'arn:aws:iam::ACCOUNT-ID:root'
Action:
- s3:GetObject
- s3:ListBucket
Resource:
- !Sub '${SharedBucket.Arn}/*'
- !GetAtt SharedBucket.Arn
yaml
`
$1
$1
Password policy configuration using CloudFormation:
` Resources:
PasswordPolicy:
Type: 'AWS::IAM::AccountPasswordPolicy'
Properties:
MinimumPasswordLength: 14
RequireLowercaseCharacters: true
RequireUppercaseCharacters: true
RequireNumbers: true
RequireSymbols: true
MaxPasswordAge: 90
PasswordReusePrevention: 24
HardExpiry: true
yaml
`
MFA device lifecycle:
` stateDiagram-v2
[*] --> Requested
Requested --> Assigned
Assigned --> Active
Active --> Deactivated
Deactivated --> [*]
Active --> Lost
Lost --> Replaced
Replaced --> Active
mermaid
`
$1
Access key rotation workflow:
` sequenceDiagram
participant Admin
participant IAM
participant Application
Admin->>IAM: Create new access key
IAM-->>Admin: Return new credentials
Admin->>Application: Update application with new key
Application-->>Admin: Confirm key works
Admin->>IAM: Deactivate old key
Admin->>IAM: Delete old key
mermaid
`
$1
$1
CloudWatch dashboard for IAM monitoring:
` Resources:
IAMDashboard:
Type: 'AWS::CloudWatch::Dashboard'
Properties:
DashboardName: IAMMonitoring
DashboardBody: !Sub |
{
"widgets": [
{
"type": "metric",
"properties": {
"metrics": [
["AWS/IAM", "AuthorizationSuccessCount"],
[".", "AuthorizationFailureCount"],
[".", "ConsoleSignInFailures"]
],
"period": 300,
"stat": "Sum",
"region": "${AWS::Region}",
"title": "IAM Authorization Metrics"
}
}
]
}
yaml
`
$1
Access Analyzer findings workflow:
` graph TD
A[Access Analyzer] -->|Analyzes| B[Resource Policies]
B -->|Generates| C[Findings]
C -->|Review| D{Action Required?}
D -->|Yes| E[Update Policy]
D -->|No| F[Archive Finding]
E -->|Verify| G[Reanalyze]
G -->|Clear| H[Close Finding]
mermaid
`
$1
$1
Cross-account access pattern:
` sequenceDiagram
participant User
participant Account A
participant STS
participant Account B
User->>Account A: Authenticate
Account A->>STS: AssumeRole
STS-->>Account A: Temporary Credentials
Account A->>Account B: Access Resources
mermaid
`
$1
Example of an application IAM configuration:
` Resources:
ApplicationRole:
Type: 'AWS::IAM::Role'
Properties:
RoleName: ApplicationServiceRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- ecs-tasks.amazonaws.com
- lambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: ApplicationPermissions
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:GetItem
- s3:GetObject
Resource: '*'
yaml
`
$1
Temporary access workflow:
` stateDiagram-v2
[*] --> RequestSubmitted
RequestSubmitted --> Approved
RequestSubmitted --> Rejected
Approved --> AccessGranted
AccessGranted --> AccessExpired
AccessExpired --> [*]
Rejected --> [*]
mermaid
``
Why This Matters
Understanding the business and technical context helps you make informed decisions rather than blindly following patterns.
Trade-offs to Consider
Every architectural decision involves trade-offs. Consider your specific requirements, team expertise, and scale when evaluating options.
When NOT to Use This
Knowing when a solution doesn't apply is as valuable as knowing when it does. Consider alternatives for your specific situation.
Decision Framework
Use this framework to evaluate whether this approach is right for your use case based on your specific constraints and requirements.