How to Fix Accessdenied Calling Copyobject
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...
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
7 Answers
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"
]
}
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!
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>
You are missing the s3:GetObjectTagging and s3:PutObjectTagging permissions as outlined here: .
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": "*"
}
]
}
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.
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"
}
}
}
]
}