A user with permission to add objects to my Amazon S3 bucket is getting Access Denied errors. Why?

Last updated: 2020-11-04

An AWS Identity and Access Management (IAM) user has permission to the s3:PutObject action on my Amazon Simple Storage Service (Amazon S3) bucket. However, when they try to upload an object, they get an HTTP 403: Access Denied error. How can I fix this?

Short description

If the IAM user has the correct permissions to upload to the bucket, then check the following policies for settings that are preventing the uploads:

  • IAM user permission to s3:PutObjectAcl
  • Conditions in the bucket policy
  • Access allowed by an Amazon Virtual Private Cloud (Amazon VPC) endpoint policy

Resolution

IAM user permission to s3:PutObjectAcl

If the IAM user must update the object's access control list (ACL) during the upload, then the user also must have permissions for s3:PutObjectAcl in their IAM policy. For instructions on how to update a user's IAM policy, see Changing permissions for an IAM user.

Conditions in the bucket policy

Review your bucket policy for the following example conditions that restrict uploads to your bucket. If the bucket policy has a condition and the condition is valid, then the IAM user must meet the condition for the upload to work.

Important: When you review conditions, be sure to verify that the condition is associated with an Allow statement ("Effect": "Allow") or a Deny statement ("Effect": "Deny"). For the upload to work, the user must comply with the condition of an Allow statement, or avoid the condition of a Deny statement.

Check for a condition that allows uploads only from a specific IP address, similar to the following:

"Condition": {
  "IpAddress": {
    "aws:SourceIp": "54.240.143.0/24"
  }
}

If your bucket policy has this condition, the IAM user must access your bucket from the allowed IP addresses.

Check for a condition that allows uploads only when the object is a specific storage class, similar to the following:

"Condition": {
  "StringEquals": {
    "s3:x-amz-storage-class": [
      "STANDARD_IA"
    ]
  }

If your policy has this condition, then the user must upload objects with the allowed storage class. For example, the previous condition statement requires the STANDARD_IA storage class. This means that the user must upload the object with an AWS Command Line Interface (AWS CLI) command similar to the following:

aws s3api put-object --bucket DOC-EXAMPLE-BUCKET --key examplefile.jpg --body c:\examplefile.jpg --storage-class STANDARD_IA

Note: If you receive errors when running AWS CLI commands, make sure that you’re using the most recent version of the AWS CLI.

Check for a condition that allows uploads only when the object is assigned a specific access control list (ACL), similar to the following:

"Condition": {
                "StringEquals": {
                    "s3:x-amz-acl":["public-read"]
                }
            }

If your policy has this condition, then users must upload objects with the allowed ACL. For example, the previous condition requires the public-read ACL, so the user must upload the object with a command similar to the following:

aws s3api put-object --bucket DOC-EXAMPLE-BUCKET --key examplefile.jpg --body c:\examplefile.jpg --acl public-read

Check for a condition that requires that uploads grant full control of the object to the bucket owner (canonical user ID), similar to the following:

"Condition": {
  "StringEquals": {
    "s3:x-amz-grant-full-control": "id=AccountA-CanonicalUserID"
  }
}

If your policy has this condition, then the user must upload objects with a command similar to the following:

aws s3api put-object --bucket DOC-EXAMPLE-BUCKET --key examplefile.jpg --body c:\examplefile.jpg --acl bucket-owner-full-control

Check for a condition that allows uploads only when objects are encrypted by an AWS Key Management System (AWS KMS) key, similar to the following:

"Condition": {
  "StringEquals": {
    "s3:x-amz-server-side-encryption-aws-kms-key-id": "arn:aws:kms:us-east-1:111122223333:key/*"
  }
}

If your policy has this condition, then the user must upload objects with a command similar to the following:

aws s3api put-object --bucket DOC-EXAMPLE-BUCKET --key examplefile.jpg --body c:\examplefile.jpg --ssekms-key-id arn:aws:kms:us-east-1:111122223333:key/*

Check for a condition that allows uploads only when objects use a certain type of server-side encryption, similar to the following:

"Condition": {
  "StringEquals": {
    "s3:x-amz-server-side-encryption": "AES256"
  }
}

If your policy has this condition, the user must upload objects with a command similar to the following:

aws s3api put-object --bucket DOC-EXAMPLE-BUCKET --key examplefile.jpg --body c:\examplefile.jpg --server-side-encryption "AES256"

Access allowed by a VPC endpoint policy

If the IAM user is uploading objects to Amazon S3 using an Amazon Elastic Compute Cloud (Amazon EC2) instance, and that instance is routed to Amazon S3 using a VPC endpoint, you must check the VPC endpoint policy. Be sure that the endpoint policy allows uploads to your bucket.

For example, the following VPC endpoint policy allows access only to DOC-EXAMPLE-BUCKET. If your bucket isn't listed as an allowed resource, then users can't upload to your bucket using the instance in the VPC.

{
  "Statement": [{
    "Sid": "Access-to-specific-bucket-only",
    "Principal": "*",
    "Action": [
      "s3:PutObject"
    ],
    "Effect": "Allow",
    "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
  }]
}

Additionally, if users upload objects with an ACL, then the VPC endpoint policy must also grant access to the s3:PutObjectAcl action, similar to the following:

{
  "Statement": [{
    "Sid": "Access-to-specific-bucket-only",
    "Principal": "*",
    "Action": [
      "s3:PutObject",
      "s3:PutObjectAcl",
    ],
    "Effect": "Allow",
    "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
  }]
}

Did this article help?


Do you need billing or technical support?