Search code examples
amazon-web-servicesamazon-s3amazon-ses

unable to access stored email in s3 via public link


I am working on a project in which I need to store the email in S3 and then access it via a public link. The email is being successfully received and stored in S3 bucket the issue is that I am unable to access the stored email publicly. In order to access it, I have to manually make it public from the console. I have set the bucket policies correctly and just for testing it I uploaded the image and then access it via the public link and it was accessible but incase of email it is not.

Here are the policy configurations of my bucket:

{
    "Version": "2012-10-17",
    "Id": "Policy1562997205894",
    "Statement": [
        {
            "Sid": "Stmt1562997204081",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::payprworkbucket",
                "arn:aws:s3:::payprworkbucket/*"
            ]
        }
    ]
}

I have searched a lot and found this solution but it is also not working for me. Please tell me how to solve this issue any help would be appreciated.


Solution

  • As the very last answer by an AWS official in the AWS forum describes [1], the SES service puts the objects into S3 using the bucket-owner-full-control canned ACL.

    Looking at the docs for bucket-owner-full-control [2], they state:

    Both the object owner and the bucket owner get FULL_CONTROL over the object. If you specify this canned ACL when creating a bucket, Amazon S3 ignores it.

    Therefore I think, the ACL grants the bucket owner permission to read the object which was placed into the bucket by SES. It also grants the owner permission to do some more actions such as s3:PutObject, s3:DeleteObject, s3:GetObjectAcl, s3:PutObjectAcl. [3] However, the grant is not specified for everyone.

    In order to allow public read access to the object, you could just manually update the ACL of each object using owner account permissions. Just grant the canned ACL public-read via the following cli command: aws s3api put-object-acl --bucket awsexamplebucket --key exampleobject --acl public-read [4][5]

    How to do this at scale?

    There is an article which describes how to apply a canned acl to a large number of objects. [6]

    Another approach would be to use S3 Cross Region Replication. There is an option which changes the replica owner (source and destination bucket owner must be different for this approach to work). [7][8] Once bucket owner and object owner are the same, the policy in question above should work fine.

    Finally, you could configure S3 Event Notifications [9] to trigger a Lambda function which copies any incoming file (to another bucket or another key) which effectively changes the owner of the newly created object.

    References

    [1] https://forums.aws.amazon.com/thread.jspa?threadID=219058
    [2] https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl
    [3] https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#acl-access-policy-permission-mapping
    [4] https://aws.amazon.com/de/premiumsupport/knowledge-center/read-access-objects-s3-bucket/
    [5] https://docs.aws.amazon.com/cli/latest/reference/s3api/put-object-acl.html
    [6] https://alexwilson.tech/blog/2017/11/30/updating-permissions-in-large-s3-buckets/
    [7] https://docs.aws.amazon.com/AmazonS3/latest/dev/crr-change-owner.html
    [8] https://docs.aws.amazon.com/AmazonS3/latest/dev/crr-walkthrough-3.html
    [9] https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html