11

I'm trying to copy files from a bucket in A account to another bucket but in B account. When I try to sync the files with the command

aws s3 sync s3://BUCKET_A s3://BUCKET_B

It returns the following output:

copy failed: s3://BUCKET_A to s3://BUCKET_B An error occurred (AccessDenied) when calling the CopyObject operation: Access Denied

This is the policy that was attached to user created in in B account (where will be copied files from bucket A):

{
    "Version": "2012-10-17",
    "Statement": [
      {
          "Effect": "Allow",
          "Action": [
              "s3:ListBucket",
              "s3:GetObject",
              "s3:PutObject",
              "s3:PutObjectAcl"
          ],
          "Resource": [
              "arn:aws:s3:::BUCKET_A",
              "arn:aws:s3::: BUCKET_A/*"
          ]
      },
      {
          "Effect": "Allow",
          "Action": [
              "s3:ListBucket",
              "s3:GetObject",
              "s3:PutObject",
              "s3:PutObjectAcl"
          ],
          "Resource": [
              "arn:aws:s3:::BUCKET_B",
              "arn:aws:s3:::BUCKET_B/*"
          ]
      }
    ]
}

Probably I missing some permission? I don't find the permission CopyObject to add in my user/bucket policy

Carlos Andres
  • 12,740
  • 7
  • 18
  • 34

9 Answers9

11

On your IAM Role Policy side you will need the following:

  {
    "Version": "2012-10-17",
    "Statement": [
      {
          "Effect": "Allow",
          "Action": [
              "s3:ListBucket",
              "s3:GetObject",
              "s3:PutObject",
              "s3:PutObjectAcl"
          ],
          "Resource": [
              "arn:aws:s3:::BUCKET_A",
              "arn:aws:s3::: BUCKET_A/*"
          ]
      },
      {
          "Effect": "Allow",
          "Action": [
              "s3:ListBucket",
              "s3:GetObject",
              "s3:PutObject",
              "s3:PutObjectAcl"
          ],
          "Resource": [
              "arn:aws:s3:::BUCKET_B",
              "arn:aws:s3:::BUCKET_B/*"
          ]
      }
    ]
}

You need to add these permissions to BUCKET_B

{
         "Sid": "Example permissions",
         "Effect": "Allow",
         "Principal": {
            "AWS": "arn:aws:iam::your_iam_policy"
         },
         "Action": [
              "s3:ListBucket",
              "s3:GetObject",
              "s3:PutObject",
              "s3:PutObjectAcl"
          ],
         ],
         "Resource": [
            "arn:aws:s3:::BUCKET_B"
         ]
      }
  • 1
    If your buckets are not cross account you just need to make sure the role has access to your bucket that you are writing to. If they are cross account you need to allow the Iamrole permissions on the bucket policy side. –  Feb 25 '19 at 22:47
  • 3
    The buckets are in differents aws account. I did the following: https://medium.com/tensult/copy-s3-bucket-objects-across-aws-accounts-e46c15c4b9e1. I have access to list but when I want to copy from a bucket to another the permission is denied like I told in the question :/ ! – Carlos Andres Feb 26 '19 at 02:11
  • My apologizes, try following this as well, https://docs.aws.amazon.com/AmazonS3/latest/dev/example-walkthroughs-managing-access-example2.html –  Feb 26 '19 at 03:37
  • hi turtle! No problem :) I fixed the issue. Apparently the permission that I missed was to the B user in policy bucket of account A. Let me clean the code and check and I will to response again with the final solution ! – Carlos Andres Feb 26 '19 at 14:36
  • In my case I added `IAMFullAccess` so there was no error. Thanks to @ user8128927 – Th Yoon Apr 14 '20 at 04:44
  • If the buckets are in different accounts this article can be followed: https://aws.amazon.com/premiumsupport/knowledge-center/copy-s3-objects-account/ Rembember to use parameter `--acl bucket-owner-full-control` in the copy command. – Eastman Nov 17 '22 at 13:11
  • On your IAM Role Policy side you will need the following: this code should go in thew bucket policy of account A right? – kd12345 Nov 22 '22 at 11:41
4

In my case, I had no issues with some objects, however one of them had that same CopyObject error stated in the question. I was also using the sync command between cross-account buckets.

So I took a look at the Event History in AWS CloudTrail (since I had cloudtrail setup) - this helps to see what API calls are being invoked. However I did not have event logging for S3 buckets and objects enabled, so I tried a couple of changes, starting with put*, which worked. I then narrowed quickly to the one that I needed.

Ultimately, that let me to add this permission to my bucket policy: s3:PutObjectTagging.

Hope this helps you out too!

Michael Behrens
  • 911
  • 10
  • 8
2

You are missing the s3:GetObjectTagging and s3:PutObjectTagging permissions as outlined here: https://medium.com/collaborne-engineering/s3-copyobject-access-denied-5f7a6fe0393e.

koziez
  • 170
  • 2
  • 6
1

I followed this approach

https://aws.amazon.com/premiumsupport/knowledge-center/copy-s3-objects-account/

to copy/sync objects from source aws account bucket to destination aws account bucket. It worked well for me.

Sethuraman Srinivasan
  • 1,528
  • 1
  • 20
  • 34
0

You'll need to configure AWS CLI on your local machine with the IAM user on B account.

You can have as many profiles as you'd like on your local cli configuration. Refer to AWS CLI configuration for more details.

Now while copying, add --profile parameter to your sync command. eg.

aws s3 sync s3://BUCKET_A s3://BUCKET_B --profile <NEW-AWS-CLI-PROFILE-FOR-ACCOUNT-B>
priteshbaviskar
  • 2,139
  • 2
  • 20
  • 27
0

This is probably related to the object's encryption in the destination bucket. Looking at the IAM role you pasted, looks like all the required permissions are granted.

To solve this problem, run the same command and add to it --sse AES256.

aws s3 sync s3://BUCKET_A s3://BUCKET_B --sse AES256

To check the encryption settings of the target bucket, you have to check the bucket policy, which should have the condition:

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

You can find the bucket policy in the tab Permissions => Bucket policy in S3 GUI, once you're in the destination bucket.

Rshad Zhran
  • 496
  • 4
  • 17
0

In my case, it worked.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:PutObject",
                "s3:GetObjectAcl",
                "s3:GetObject",
                "s3:PutObjectVersionAcl",
                "s3:GetObjectTagging",
                "s3:DeleteObject",
                "s3:GetBucketLocation",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3:::source-bucket/*",
                "arn:aws:s3:::destination-bucket/*",
                "arn:aws:s3:::source-bucket",
                "arn:aws:s3:::destination-bucket"
            ]
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "s3:ListAllMyBuckets",
            "Resource": "*"
        }
    ]
}
nkhl143
  • 1
  • 3
  • Hi Nikhil, Improve your answer with additional information. Like explaining your code for better understanding. – pmadhu Sep 16 '21 at 11:50
0

Please note that I am basing my answer off of Micheal's answer.

In my case I needed to have in addition to the s3:GetObject and s3:ListObject I needed to have the s3:GetObjectTagging permission

For further reference

In summary my source bucket policy looked like below:

        {
            "Sid": "DelegateS3Access",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::destination-account:root"
            },
            "Action": [
                "s3:ListBucket",
                "s3:GetObject",
                "s3:GetObjectTagging"
            ],
            "Resource": [
                "arn:aws:s3:::source-bucket/*",
                "arn:aws:s3:::source-bucket"
            ]
        }

Please also keep in mind I had AdminstratorAccess in the destination account so I didn't have to attach anything in the IAM role of my destination user

Ganesh Hegde
  • 101
  • 3
-4
  1. disable block public access
  2. leave the bucket unencrypted
  3. look up your public ip:
  4. add below policy to the s3 bucket
{
    "Version": "2008-10-17",
    "Id": "Policy1357935677554",
    "Statement": [
        {
            "Sid": "Stmt1357935647218",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::YOUR-S3-BUCKET-NAME",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": "YOUR-PUBLIC-IP/32"
                }
            }
        },
        {
            "Sid": "Stmt1357935676138",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::YOUR-S3-BUCKET-NAME/*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": "YOUR-PUBLIC-IP/32"
                }
            }
        }
    ]
}
BDL
  • 21,052
  • 22
  • 49
  • 55
alex
  • 11
  • 1