S3 permission issue

Hi there,

I’ve created an integration with Shotstack on our server and are looking to upload renders to our S3 bucket.

I’ve followed all the guides I can and looked in this forum and didn’t find any other issues like mine.

These are the permissions of our IAM user in AWS:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::[redacted-for-privacy]/*"
        }
    ]
}

I’ve also tried FULL access to S3 for IAM user with “s3:*” (full access) but no luck there either.

"destinations": [{
    "provider": "s3",
    "options": {
        "region": "ca-central-1",
        "bucket": "[redacted-for-privacy]",
        "prefix": "slideshows",
        "acl": "public-read"
    }
},{
    "provider": "shotstack",
    "exclude": true
}]

We are still getting the “Failed to copy file to S3. Access denied, check credentials or S3 IAM permissions.” error.

I’ve checked everything I can on my end and the user has the correct permissions.

I’ve tried enabling ACL’s on the bucket, no luck there. I tried removing the “acl” param from setDestination, I’ve tried staging / production environments to see if there was limitations, with no luck there.

At a loss for what to do next.

Using PHP7 SDK

Please let me know what the issue might be.

We have just pushed this PHP demo which uses the latest version of the SDK (v0.2.3), I have tested this against one of our buckets and can confirm it work without any issues: php-demos/s3.php at main · shotstack/php-demos · GitHub

Will investigate your particular issue and try to find requests in the logs. Will also try some different permissions and try to narrow that down to the minimum set of permissions.

The best I have been able to do so far is:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::*"
            ]
        }
    ]
}

This might be a bit too permissive for you. I suspect there is an action that needs access to all your buckets or some global feature of S3 and then you can restrict the putObject to just the bucket. But I haven’t been able to figure that out yet.

I have sent a support ticket to AWS to see if they can help.

@lucas.spielberg Hey, any update on this? We still haven’t been able to figure it out.

This is as locked down as I have been able to get it on the external AWS account I am testing with:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::shotstack-s3-integration-au/*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObjectAcl",
                "s3:GetObjectAttributes",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads",
                "s3:AbortMultipartUpload",
                "s3:ListMultipartUploadParts"
            ],
            "Resource": "arn:aws:s3:::*"
        }
    ]
}

Also the bucket object ownership looks like this:

This is the best I have been able to do. If you need stricter controls there are a few things you can do:

  1. Create a separate AWS account for storing objects sent by us
  2. Copy the temporary URL we provide to you when the video/image finishes rendering and create your own script/process to copy the file to your S3 bucket. That way you do not need to provide us with credentials but you will have to code the copy function yourself.
1 Like

@lucas.spielberg My bucket policy is also as follows:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AddPerm",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::[redacted-for-privacy]/*"
        }
    ]
}

Do you see any issue with this?

It looks like it should work but I have tried this and similar and I haven’t been able to get it to work. The example I posted is the best I have been able to do. Also you might need multipart permissions if you render large files.

Also I am using a user policy and not a bucket policy. If this is a Bucket policy and the Principal is “*”, I think that means any AWS account can put and get objects from that bucket.

[EDIT]

I created a brand new bucket and tried this from scratch.

  • I removed bucket policy (not sure if this was the culprit)
  • Used the IAM permission that @lucas.spielberg provided above
  • ACL’s enabled (same as Lucas’s screenshot above)
  • Block all public access turned off
  • Removed “prefix” from code (not sure if this was the culprit either)

And… it worked! Thanks!

Have you tried this user policy, it should have no restrictions. I’d start with the least restrictions that work and then tighten them: S3 permission issue - #3 by lucas.spielberg

Did you remove the bucket policy and only use the user policy?

Must have been the Bucket Policy, but I’m not sure why it would restrict access. That bucket works fine for my S3 integration on Laravel (uploading photos/videos). I need that Bucket Policy for my other objects to have public view access, so I just created a new bucket instead for slideshows.

The bucket and user policy get merged as far as I know so you probably end up with a mish-mash of rules. It could be because the file is being uploaded from another AWS account or how the library copies the file which makes it slightly different from a regular upload. I agree and would expect the rules you had to work but I also had the same issues when testing to one of my own buckets in a different AWS account.

1 Like

Is there a way we can see the error code returned by aws? That way we can debug better our implementation

How do you have this settings?