I have created a multi-region access point (MRAP) to access replicated buckets across different locations. I have a Flask API that uses boto3 to connect to S3 and make requests. According to AWS, for SDK requests for MRAP, the bucket name should be given as the ARN of the MRAP, while for REST API requests, the hostname of the MRAP should be used.
One thing I do with my Flask API is that there a route available that allows the user to make a request where the user can provide a Key for a new file to be placed onto S3, and the API uses the generate_presigned_post() function of boto3 to generate a presigned URL/fields and send this back to the user. The user can then make a POST request to this presigned URL with the file they want to upload.
When using an MRAP, this causes issues. My Flask API uses the ARN to identify the MRAP, and so when calling generate_presigned_post(), it sets the bucket name value to the ARN. This request seems to work fine, and returns the policy/signature under "fields" and also the URL, which is in this format:
"https://s3.amazonaws.com/arn%3Aaws%3As3%3A%3A<my_account_id>%3Aaccesspoint%2F<my_mrap_alias.mrap>"
The problem now is that if I go to POST a file to this URL using the provided fields, I get an error saying the bucket name is invalid:
<Error><Code>InvalidBucketName</Code><Message>The specified bucket is not '
'valid.</Message><BucketName>arn:aws:s3::<my_account_id>:accesspoint</BucketName>...</Error>
It seems the MRAP alias at the end of the ARN is getting cut off somehow. I think this is related to how AWS says you must use the hostname for REST API requests. So I tried to ignore the URL given to me by generate_presigned_post() and instead make the same POST request for uploading the file with the same fields, except using the hostname as the URL, this format:
"https://<my_mrap_alias.mrap>.accesspoint.s3-global.amazonaws.com"
This also results in an error:
<Error><Code>AccessDenied</Code><Message>Invalid according to Policy: Policy '
'Condition failed: ["eq", "$bucket", '
'"arn:aws:s3::<my_account_id>:accesspoint/<my_mrap_alias.mrap>"]</Message>...</Error>
This tells me that it seems like the request goes through properly, but since generate_presigned_post() had used the ARN for creating the presigned URL, the policy tries to directly compare the ARN to the hostname given in the POST request as if they are supposed to both be the same literal bucket name.
Is there any solution to this? Is there any way to generate presigned POST URLs through boto3 that are actually able to be POST'ed to without this error popping up? To me, this feels like a condition that has been overlooked by AWS so far but maybe I am missing something.