Aws
AwsIntermediate

An Overview of AWS Identity and Access Management (IAM)

12 min read
awsiamsecurityaccess-managementcloud-security

TL;DR

A comprehensive guide to understanding AWS IAM concepts, policies, and best practices for secure access management in your AWS infrastructure.

AWS Identity and Access Management (IAM) for Experienced Engineers

TL;DR: AWS IAM is the foundational service for controlling access to AWS resources. It allows granular permission management for users, applications, and services through policies. Effective IAM implementation relies on understanding its components, policy types, security best practices, and monitoring capabilities to enforce the principle of least privilege.

$1

AWS Identity and Access Management (IAM) is the cornerstone of AWS security, providing a robust framework for managing access to AWS services and resources. For seasoned engineers, IAM is not just a feature but a critical component of system architecture, essential for maintaining security, compliance, and operational efficiency. It empowers organizations to define precisely who can do what, on which resources, and under what conditions, directly supporting the principle of least privilege. This document provides a deep dive into IAM, targeting experienced professionals.

$1

IAM's power lies in its modular design, allowing for flexible and precise access control.

$1

* IAM Users: Represent an entity (person, application, or service) that requires AWS credentials to interact with AWS.

* IAM Groups: A collection of IAM users. Permissions are assigned to groups, and any user within that group inherits those permissions. This simplifies management by allowing you to grant common access rights to multiple users.

IAM Roles: Act as an identity that an application or service can *assume to obtain temporary AWS credentials. Roles are ideal for granting permissions to AWS services (e.g., EC2 instances, Lambda functions) or for cross-account access. They do not have long-term credentials like passwords or access keys associated with them.

Example: Managing Users and Groups with CloudFormation

This CloudFormation snippet demonstrates creating an IAM group with a managed policy and a user assigned to that group.

``yaml

Resources:

DevelopersGroup:

Type: 'AWS::IAM::Group'

Properties:

GroupName: Developers

# PowerUserAccess grants broad permissions, consider a more scoped policy for production.

ManagedPolicyArns:

- arn:aws:iam::aws:policy/PowerUserAccess

DeveloperUser:

Type: 'AWS::IAM::User'

Properties:

UserName: john.doe

Groups:

- !Ref DevelopersGroup

# For programmatic access, password is not required. Manage programmatic access keys separately.

LoginProfile:

Password: !Ref 'UserPassword' # Sensitive, use AWS Secrets Manager or Parameter Store

PasswordResetRequired: true

DeveloperAccessKey:

Type: 'AWS::IAM::AccessKey'

Properties:

UserName: !Ref DeveloperUser

`

$1

Policies are JSON documents that define permissions. IAM evaluates policies to determine whether to allow or deny an action.

* Identity-Based Policies: Attached to an IAM identity (user, group, or role). These policies define what actions that identity can perform.

* Resource-Based Policies: Embedded in an AWS resource (e.g., an S3 bucket policy, an IAM policy for an IAM role). These policies define which principals are allowed to access the resource and under what conditions.

Policy Evaluation Logic:

Requests to AWS services are evaluated against both identity-based and resource-based policies (if applicable). The evaluation follows these rules:

1. Explicit Deny: If any applicable policy explicitly denies the action, the request is denied.

2. Explicit Allow: If no explicit deny is found, and at least one applicable policy explicitly allows the action, the request is allowed.

3. Default Deny: If neither of the above conditions is met, the request is implicitly denied.

`mermaid

flowchart TB

A[Request for Action] --> B{Explicit Deny in any applicable policy?}

B -->|Yes| C[Deny Access]

B -->|No| D{Explicit Allow in any applicable policy?}

D -->|Yes| E[Allow Access]

D -->|No| F[Default Deny Access]

style C fill:#f96,stroke:#333,stroke-width:2px

style E fill:#9f6,stroke:#333,stroke-width:2px

`

Example: Custom Policy with Conditions for EC2 Management

This policy grants permissions to manage EC2 instances, but only for specific instance types and within defined regions. This demonstrates the power of Condition elements for fine-grained control.

`json

{

"Version": "2012-10-17",

"Statement": [

{

"Sid": "AllowEC2ManagementInSpecificRegionsAndTypes",

"Effect": "Allow",

"Action": [

"ec2:RunInstances",

"ec2:StartInstances",

"ec2:StopInstances",

"ec2:TerminateInstances"

],

"Resource": "*", # Note: Resource can be further restricted for better security

"Condition": {

"StringEquals": {

"aws:RequestedRegion": ["us-east-1", "eu-west-1"]

},

"StringLike": {

"ec2:InstanceType": ["t2.", "t3.*", "m5."]

}

}

}

]

}

`

Example: S3 Bucket Policy for Cross-Account Access

This S3 bucket policy explicitly grants GetObject and ListBucket permissions to a specific AWS account (replace ACCOUNT-ID with the actual account ID).

`yaml

Resources:

SharedBucket:

Type: 'AWS::S3::Bucket'

Properties:

BucketName: my-shared-data-bucket

# Additional bucket configurations...

BucketPolicy:

Type: 'AWS::S3::BucketPolicy'

Properties:

Bucket: !Ref SharedBucket

PolicyDocument:

Version: '2012-10-17'

Statement:

- Sid: AllowCrossAccountReadAccess

Effect: Allow

Principal:

AWS: 'arn:aws:iam::ACCOUNT-ID:root' # Replace with the target account ID

Action:

- s3:GetObject

- s3:ListBucket

Resource:

- !Sub '${SharedBucket.Arn}/*' # Grants access to objects within the bucket

- !GetAtt SharedBucket.Arn # Grants access to the bucket itself (for ListBucket)

`

$1

IAM Roles are paramount for providing AWS services with necessary permissions without embedding long-term credentials.

Example: EC2 Instance Role for S3 and RDS Read Access

This role allows an EC2 instance to assume it, granting it read-only access to S3 buckets and RDS instances.

`yaml

Resources:

EC2ServiceRoleForReadAccess:

Type: 'AWS::IAM::Role'

Properties:

RoleName: EC2ReadAccessRole

AssumeRolePolicyDocument:

Version: '2012-10-17'

Statement:

- Effect: Allow

Principal:

Service: ec2.amazonaws.com # Allows EC2 service to assume this role

Action: sts:AssumeRole

ManagedPolicyArns:

- arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

- arn:aws:iam::aws:policy/AmazonRDSReadOnlyAccess

`

Diagram: IAM Role Assumption Flow

`mermaid

graph LR

subgraph AWS Environment

A[Principal (e.g., EC2 Instance)] -->|1. Initiates AssumeRole| B(AWS Security Token Service - STS)

B -->|2. Validates Trust Policy| C(IAM Role)

C -->|3. Returns Temporary Credentials| B

B -->|4. Credentials provided to Principal| A

A -->|5. Accesses AWS Services using temporary credentials| D(AWS Services)

end

subgraph IAM Configuration

E[IAM Role Trust Policy]

F[IAM Role Permissions Policy]

E --> C

F --> C

end

style B fill:#f9f,stroke:#333,stroke-width:2px

`

$1

Implementing robust security practices is non-negotiable for effective IAM.

$1

* Password Policies: Enforce complexity, length, and rotation requirements for IAM user console passwords.

* MFA: Crucial for protecting privileged accounts. Enable MFA for all IAM users, especially those with administrative access.

Example: Enforcing a Strong Password Policy with CloudFormation

`yaml

Resources:

IAMAccountPasswordPolicy:

Type: 'AWS::IAM::AccountPasswordPolicy'

Properties:

MinimumPasswordLength: 14

RequireLowercaseCharacters: true

RequireUppercaseCharacters: true

RequireNumbers: true

RequireSymbols: true

MaxPasswordAge: 90 # Days

PasswordReusePrevention: 24 # Number of passwords to prevent reuse

HardExpiry: true

`

MFA Device Lifecycle Overview:

`mermaid

stateDiagram-v2

[*] --> NotConfigured : User account created

NotConfigured --> SetupInProgress : User initiates MFA setup

SetupInProgress --> Assigned : MFA device registered (e.g., virtual MFA app)

Assigned --> Active : MFA device is in use and validated

Active --> Deactivated : MFA device disabled (e.g., user rotated)

Deactivated --> [*] : Device removed

Active --> Lost : Device reported lost/stolen

Lost --> ReplacementInProgress : User requests a new device

ReplacementInProgress --> Assigned : New device registered

`

$1

Access keys (Access Key ID and Secret Access Key) grant programmatic access to AWS. They are powerful credentials and must be managed with extreme care.

* Minimize Usage: Prefer IAM roles for applications running on AWS services.

* Rotation: Implement a regular access key rotation schedule.

* Avoid Embedding: Do not hardcode access keys in application code or configuration files. Use environment variables, AWS Secrets Manager, or AWS Systems Manager Parameter Store.

* Least Privilege: Grant access keys only the permissions they strictly require.

Access Key Rotation Workflow:

`mermaid

sequenceDiagram

participant Admin/Automation

participant IAM

participant Application/Service

Admin/Automation->>IAM: Create new IAM access key for user/role

IAM-->>Admin/Automation: Return new Access Key ID and Secret Access Key

Admin/Automation->>Application/Service: Update configuration with new credentials securely (e.g., via Secrets Manager)

Application/Service-->>Admin/Automation: Confirm successful connection/operation with new credentials

Admin/Automation->>IAM: Deactivate the old access key

Admin/Automation->>IAM: Delete the old access key after a validation period

`

$1

Continuous monitoring and auditing are essential to maintain security posture and meet compliance requirements.

$1

* AWS CloudTrail: Records API calls made in your AWS account, providing an audit trail of actions taken by users, roles, and AWS services.

* Amazon CloudWatch Logs: Collects logs from various AWS services, including logs generated by IAM, for analysis and monitoring.

Example: CloudWatch Dashboard for IAM Metrics

This CloudWatch dashboard visualizes key IAM authorization metrics.

`yaml

Resources:

IAMMonitoringDashboard:

Type: 'AWS::CloudWatch::Dashboard'

Properties:

DashboardName: IAMSecurityMonitoring

DashboardBody: !Sub |

{

"widgets": [

{

"type": "metric",

"properties": {

"metrics": [

["AWS/IAM", "AuthorizationSuccessCount", "ServiceName", "EC2"], # Example for a specific service

[".", "AuthorizationFailureCount", "ServiceName", "S3"], # Example for another service

[".", "ConsoleSignInFailures", "UserName", "admin*"] # Monitoring failed console sign-ins for admin users

],

"view": "timeSeries",

"stacked": false,

"region": "${AWS::Region}",

"stat": "Sum",

"period": 300, # 5-minute intervals

"title": "IAM Authorization and Sign-in Failures"

}

},

{

"type": "text",

"properties": {

"markdown": "## IAM Activity Summary\nThis dashboard provides insights into IAM authorization events and failed sign-in attempts."

}

}

]

}

`

$1

IAM Access Analyzer helps identify resources that are shared with external entities, such as other AWS accounts or anonymous users. It continuously monitors your resources for unintended public or cross-account access.

Access Analyzer Findings Workflow:

`mermaid

graph TD

A[IAM Access Analyzer] -->|Scans| B(Resource Policies and IAM Policies)

B -->|Identifies| C[Potential Access Findings]

C -->|Categorizes| D{Access Type (e.g., Public, Cross-Account)}

D -->|Reports| E[Access Analyzer Findings Console/API]

E -->|Review| F{Action Required?}

F -->|Yes| G[Update Policy/Resource Configuration]

F -->|No| H[Archive Finding / Document Decision]

G -->|Re-scan| I[Access Analyzer Validation]

I -->|If secured| J[Finding Resolved/Closed]

`

$1

$1

Enables secure access between AWS accounts, essential for centralized security or shared service models.

Pattern: Cross-Account IAM Role Assumption

1. A user or service in Account A needs to access resources in Account B.

2. An IAM Role is configured in Account B with a Trust Policy allowing principals from Account A to assume it.

3. The principal in Account A uses AWS STS (AssumeRole API) to assume the role in Account B.

4. STS returns temporary credentials for the assumed role.

5. The principal in Account A uses these temporary credentials to access resources in Account B.

`mermaid

sequenceDiagram

participant User/Service (Account A)

participant AWS STS

participant IAM Role (Account B)

participant Resources (Account B)

User/Service (Account A)->>AWS STS: AssumeRole(RoleArn='arn:aws:iam::ACCOUNT-B-ID:role/MyCrossAccountRole', RoleSessionName='session-abc')

AWS STS->>IAM Role (Account B): Validate Trust Policy for Account A

IAM Role (Account B)-->>AWS STS: Trust Policy allows Account A

AWS STS-->>User/Service (Account A): Temporary Credentials (AccessKeyId, SecretAccessKey, SessionToken)

User/Service (Account A)->>Resources (Account B): Perform action using temporary credentials (e.g., s3:GetObject)

`

$1

Granting specific permissions to applications running on AWS services like EC2, Lambda, or ECS.

Example: IAM Role for ECS Task with DynamoDB and S3 Access

This role is designed for an ECS task, allowing it to interact with DynamoDB and S3.

`yaml

Resources:

ApplicationServiceRole:

Type: 'AWS::IAM::Role'

Properties:

RoleName: ECSApplicationServiceRole

AssumeRolePolicyDocument:

Version: '2012-10-17'

Statement:

- Effect: Allow

Principal:

Service: ecs-tasks.amazonaws.com # Service that can assume this role

Action: sts:AssumeRole

# Basic execution role for logging and other common tasks

ManagedPolicyArns:

- arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRoleAccess

Policies:

- PolicyName: AppSpecificPermissions

PolicyDocument:

Version: '2012-10-17'

Statement:

- Effect: Allow

Action:

- dynamodb:Query

- dynamodb:GetItem

- dynamodb:PutItem

- s3:GetObject

- s3:PutObject

Resource: # Restrict to specific table ARNs and bucket ARNs

- !Sub 'arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/MyAppDataTable'

- !Sub 'arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/MyUserTable'

- !Sub 'arn:aws:s3:::my-app-bucket/*'

`

$1

Providing time-bound access for specific tasks, often for auditing, temporary support, or controlled deployments. This is typically managed by assuming a role with a defined duration.

Workflow: A user or service requests temporary access. This request is approved, and the user/service assumes an IAM role that has been configured with policies and potentially a maximum session duration. The credentials obtained are valid only for that session duration.

`mermaid

stateDiagram-v2

[*] --> RequestSubmitted : User/Service requests access

RequestSubmitted --> Approved : Access request is granted

RequestSubmitted --> Rejected : Access request is denied

Approved --> AccessGranted : User/Service assumes role and receives temporary credentials

AccessGranted --> AccessExpired : Session duration reaches its limit

AccessExpired --> [*] : Credentials are no longer valid

Rejected --> [*] : Access denied, no credentials issued

`

$1

* Complexity vs. Security: More granular policies offer better security but increase management complexity. Balancing this is key.

* Managed Policies vs. Inline Policies: Managed policies (AWS-managed or customer-managed) offer reusability and easier updates. Inline policies are embedded directly into an identity or resource and are specific to that entity, useful for unique, one-off permissions.

Performance: While IAM evaluation is generally fast, overly complex policies or a very large number of policies attached to a single principal *can theoretically introduce minor overhead. However, this is rarely a bottleneck in practice for most applications.

* Cost: IAM itself is free. However, the resources secured by IAM have associated costs. Misconfigurations leading to unauthorized resource usage can incur significant costs.

Service Control Policies (SCPs) in AWS Organizations: For multi-account environments, SCPs provide a layer of governance to define the *maximum* permissions available to accounts, complementing IAM policies which define *what permissions are granted.

$1

Not for Network Firewalling: IAM controls *access to AWS APIs and resources, not network traffic filtering. Use Security Groups and Network ACLs for network-level access control.

Not for Application-Level Authorization: IAM defines *who can access AWS resources. Application-level authorization (e.g., user roles within your application, data row-level security) must be implemented within the application logic itself.

Not for Secrets Management (Solely): While IAM can grant access to secrets (e.g., via Secrets Manager), it's not a replacement for a dedicated secrets management solution. IAM policies should control *access to secrets, not manage the secrets themselves.

$1

Before implementing or modifying IAM configurations, consider the following:

[ ] Principle of Least Privilege: Does this policy grant *only the necessary permissions?

* [ ] Identity Type: Is this for a human user, an application, or a service? Choose User, Group, or Role accordingly.

* [ ] Credential Management: If using access keys, is there a plan for rotation and secure storage? Are roles a viable alternative?

* [ ] Policy Scope: Is the policy too broad? Can Resource elements and Condition` blocks be used to restrict access further?

* [ ] Auditing: Are CloudTrail logs enabled and configured for relevant events?

* [ ] MFA: Is MFA enforced for privileged users?

* [ ] Cross-Account Access: Is the trust relationship defined correctly and narrowly scoped?

* [ ] Resource-Based Policies: Are there any resource-based policies that might override or conflict with identity-based policies?

* [ ] Service Control Policies (SCPs): In an AWS Organization, do SCPs align with or restrict IAM policies as intended?

* [ ] Regular Review: Is there a process for periodic review and cleanup of unused IAM entities and overly permissive policies?

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.