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
- 1Check caller identity: `aws sts get-caller-identity`
- 2Check bucket policy: `aws s3api get-bucket-policy --bucket <name>`
- 3Check bucket ACL: `aws s3api get-bucket-acl --bucket <name>`
- 4Check Block Public Access: `aws s3api get-public-access-block --bucket <name>`
- 5For KMS: check key policy grants to the caller
- 6Use IAM Policy Simulator to test s3 permissions
>Fix
- 1Add required S3 permissions to the IAM policy (s3:GetObject, s3:PutObject, etc.)
- 2Update bucket policy to allow the IAM entity
- 3For cross-account: add bucket policy allowing the other account AND IAM policy in that account
- 4Fix KMS key policy to allow the caller to Decrypt/Encrypt
- 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