DevOpsil
AWSHigh

Fix: AWS S3 Access Denied (403 Forbidden)

S3 operations return '403 Forbidden' or 'Access Denied'

!Symptoms

  • S3 operations return '403 Forbidden' or 'Access Denied'
  • Can list bucket but cannot get objects, or vice versa
  • Cross-account S3 access fails
  • S3 presigned URLs return Access Denied

?Root Causes

  • IAM policy does not grant s3:GetObject, s3:PutObject, etc.
  • Bucket policy explicitly denies the action or restricts by IP/VPC
  • S3 Block Public Access settings preventing access
  • Object ownership: objects uploaded by another account are not accessible
  • KMS encryption key policy does not grant decrypt to the caller
  • Wrong region: bucket is in a different region than expected

#Diagnosis Steps

  1. 1Check caller identity: `aws sts get-caller-identity`
  2. 2Check bucket policy: `aws s3api get-bucket-policy --bucket <name>`
  3. 3Check bucket ACL: `aws s3api get-bucket-acl --bucket <name>`
  4. 4Check Block Public Access: `aws s3api get-public-access-block --bucket <name>`
  5. 5For KMS: check key policy grants to the caller
  6. 6Use IAM Policy Simulator to test s3 permissions

>Fix

  1. 1Add required S3 permissions to the IAM policy (s3:GetObject, s3:PutObject, etc.)
  2. 2Update bucket policy to allow the IAM entity
  3. 3For cross-account: add bucket policy allowing the other account AND IAM policy in that account
  4. 4Fix KMS key policy to allow the caller to Decrypt/Encrypt
  5. 5If using presigned URLs, ensure the signer has the same permissions as the intended action

*Prevention

  • Use IAM Access Analyzer for S3 to find unintended public access
  • Implement bucket policies with explicit conditions (IP, VPC endpoint, MFA)
  • Use S3 Access Points for granular, per-application access patterns
  • Test S3 access patterns as part of deployment verification
  • Document bucket access patterns and required permissions for each application

Related Error Messages

403 ForbiddenAccess DeniedAccessDeniedAllAccessDisabledKMS.DisabledExceptionThe bucket does not allow ACLs