'Custom CNAME for S3 encrypted bucket using presigned URL

I'm using a presigned S3 url to upload files to a private S3 bucket with SSE-KMS encryption enabled. This is part of a web application where a user can upload files. I have a lambda that generates the presigned URL that the web client then posts to.

This all works fine when using the normal s3.Region.amazonaws.com domain but I would like to use a custom domain name instead.

Is there any way that a private and encrypted S3 bucket can be accessed using a presigned URL for a custom domain?

Here's what I've tried so far:

  • I created just a simple CNAME to the bucket and passed in that as the endpoint_url when creating the boto3 Session to generate the presigned URL.

    This works, but only using http. Using https results in an error due to the SSL certificate being for s3.Region.amazonaws.com and not my domain.

  • I tried setting up a CloudFront instance with caching disabled and s3.Region.amazonaws.com as the origin and pointed the CNAME at that. I then generated a presigned URL using the 'path' addressing style so the CloudFront instance would fetch https://s3.Region.amazonaws.com/bucket-name/object?etc, thinking that the authentication query parameters would all get passed through to S3. This didn't work and gives a 403 error.

    Using CloudFront like this does work if the bucket is made public and is not encrypted.

    It seems like maybe the query parameters added when presigning the URL don't make it as far as S3, and so because the bucket is not accessible without these it gives the 403 error.

    I have read that I could use a Lambda@Edge function to presign the S3 request, but that would limit the request size to 1mb and prevent uploading files larger than that which would be a problem for me.

I understand that I could give the CloudFront instance access to the S3 bucket and KMS key and use a presigned CloudFront URL instead. This isn't ideal for what I need as I manage different users' data in different buckets with different encryption keys. That would either require a different CloudFront instance for each user/bucket, or giving a single CloudFront instance access to all buckets and all KMS keys, neither of which seems ideal.

Is there any way of doing this, or anything else I should try?

Thanks in advance for your help! :)



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source