🎉 DevOps Interview Prep Bundle is live — 1000+ Q&A across 20 topicsGet it →
All Fixes
Today I Fixed

AWS S3 403 Access Denied even though IAM policy allows s3:GetObject

awsJul 1, 202625 minutes to fixawssecuritytroubleshooting

Lambda function in Account A was getting 403 Access Denied on every s3:GetObject call to a bucket in Account B. The IAM role attached to the Lambda had an explicit s3:GetObject allow policy. The error: An error occurred (403) when calling the GetObject operation: Forbidden.

Root cause: S3 cross-account access requires permissions to be granted from both sides. The IAM policy on the role in Account A was correct, but the bucket policy in Account B had no statement allowing Account A's role. S3 evaluates both policies — if either side denies (or doesn't explicitly allow), the request fails with 403.

Fix:

Add this statement to the S3 bucket policy in Account B:

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowCrossAccountAccess",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::111122223333:role/my-lambda-role"
      },
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::my-bucket",
        "arn:aws:s3:::my-bucket/*"
      ]
    }
  ]
}

Replace 111122223333 with Account A's ID and my-lambda-role with the actual role name.

To debug S3 permission issues quickly, use the IAM policy simulator or check CloudTrail for the denied event — it shows exactly which policy evaluation caused the deny.

Lesson: S3 cross-account access needs an allow on both the IAM role (source account) AND the bucket policy (target account) — one side alone is never enough.