# AWS IAM Permission Denied
Common Error Patterns
IAM permission errors typically appear as:
User: arn:aws:iam::123456789012:user/test is not authorized to perform: ec2:DescribeInstancesAccessDenied when calling the AssumeRole operationUser is not authorized to perform: s3:GetObject on resource: arn:aws:s3:::my-bucket/keyRoot Causes and Solutions
1. Missing IAM Policy Permissions
The user or role lacks the required action in their policy.
Solution:
Identify the missing permission and add it:
```bash # Check user policies aws iam list-user-policies --user-name test aws iam list-attached-user-policies --user-name test
# Check role policies aws iam list-role-policies --role-name MyRole aws iam list-attached-role-policies --role-name MyRole ```
Add inline policy:
aws iam put-user-policy \
--user-name test \
--policy-name EC2ReadAccess \
--policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:Describe*"
],
"Resource": "*"
}
]
}'2. Explicit Deny in Policy
A policy explicitly denies the action.
Solution:
Review all policies for deny statements:
# Get all policies for user
aws iam get-user-policy --user-name test --policy-name PolicyNameDeny statements override allow statements:
{
"Effect": "Deny",
"Action": "s3:*",
"Resource": "*"
}Remove or modify the deny statement to allow the required action.
3. Resource-Based Policy Restrictions
The resource policy doesn't allow the principal.
Solution:
For S3 buckets, check bucket policy:
aws s3api get-bucket-policy --bucket my-bucketFor cross-account access, ensure the resource policy allows the principal:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
]
}
]
}4. AssumeRole Failure
Cross-account or service role assumption fails.
Solution:
Verify trust policy allows the principal:
aws iam get-role --role-name MyRole --query 'Role.AssumeRolePolicyDocument'Trust policy example:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "my-external-id"
}
}
}
]
}Also ensure the source account has sts:AssumeRole permission:
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::999999999999:role/MyRole"
}5. Permission Boundaries
Permission boundaries restrict maximum permissions.
Solution:
Check for permission boundaries:
```bash aws iam get-user --user-name test --query 'User.PermissionsBoundary'
aws iam get-role --role-name MyRole --query 'Role.PermissionsBoundary' ```
Update boundary to allow required actions or remove boundary:
aws iam delete-user-permissions-boundary --user-name test6. Service-Linked Role Issues
Service requires a service-linked role.
Solution:
Create the required service-linked role:
aws iam create-service-linked-role \
--aws-service-name ecs.amazonaws.com7. Session Policies
Temporary credentials have session policy restrictions.
Solution:
When assuming a role, session policies limit permissions:
# Check session policies when assuming role
aws sts assume-role \
--role-arn arn:aws:iam::123456789012:role/MyRole \
--role-session-name MySession \
--policy '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"s3:*","Resource":"*"}]}'Troubleshooting Tools
IAM Policy Simulator
Use the IAM Policy Simulator to test permissions:
- 1.Navigate to IAM Console > Policy Simulator
- 2.Select user, group, or role
- 3.Select actions to test
- 4.Run simulation
AWS CLI Troubleshooting
```bash # Simulate policy aws iam simulate-principal-policy \ --policy-source-arn arn:aws:iam::123456789012:user/test \ --action-names s3:GetObject \ --resource-arns arn:aws:s3:::my-bucket/key
# Check access keys aws iam list-access-keys --user-name test
# Check user groups aws iam list-groups-for-user --user-name test ```
CloudTrail Analysis
Find the denied action in CloudTrail:
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=AccessDenied \
--max-results 10Common Scenarios
EC2 Instance Profile
```bash # Check instance profile aws iam get-instance-profile --instance-profile-name MyProfile
# Attach role to instance aws ec2 associate-iam-instance-profile \ --instance-id i-0123456789abcdef0 \ --iam-instance-profile Name=MyProfile ```
Lambda Execution Role
```bash # Check Lambda role aws lambda get-function-configuration --function-name my-function \ --query 'Role'
# Update Lambda role aws lambda update-function-configuration \ --function-name my-function \ --role arn:aws:iam::123456789012:role/LambdaExecutionRole ```
Cross-Account S3 Access
Required configuration:
- 1.Source account: Allow s3:* on bucket
- 2.Destination account: Allow s3:* on bucket policy
- 3.User policy: Allow s3:* on bucket AND sts:AssumeRole if using role
Debugging Checklist
| Check | Command |
|---|---|
| User policies | aws iam list-attached-user-policies |
| Inline policies | aws iam list-user-policies |
| Group memberships | aws iam list-groups-for-user |
| Permission boundary | aws iam get-user --query 'User.PermissionsBoundary' |
| Role trust policy | aws iam get-role --query 'Role.AssumeRolePolicyDocument' |
| Simulate access | aws iam simulate-principal-policy |
Prevention Tips
- 1.Use IAM Access Analyzer to identify unintended access
- 2.Implement least-privilege permissions
- 3.Use AWS managed policies as templates
- 4.Enable CloudTrail for audit logging
- 5.Review permissions regularly with IAM credential report
Related Articles
- [AWS S3 Access Denied](#)
- [AWS EC2 Instance Not Reachable](#)
- [AWS Lambda Timeout](#)