0

I'm attempting to use a pre-signed url for an S3 bucket with a custom endpoint. I seem so close, but I keep getting a Method Not Allowed error. Here's where I'm at.

I have an API Gateway which connects an endpoint to a Lambda function. That function, among other things, generates a pre-signed url. Like so,

var s3 = new AWS.S3({
    endpoint: 'custom.domain.com/upload',
    s3BucketEndpoint: true,
    signatureVersion: 'v4'
});

//...

s3.getSignedUrl('putObject', {
    ACL: 'bucket-owner-full-control',
    Bucket: process.env.S3_BUCKET_NAME,
    ContentType: "image/png",
    Key: asset.id + ".png"
};

This code successfully returns a url with what appears to be all the correct query params, correct key name, and the url is pointing to my endpoint. When attempting to upload however, I receive the following error:

MethodNotAllowedThe specified method is not allowed against this resource.PUTSERVICE[request id was here][host id was here]

If I remove my custom endpoint declaration from my S3 config, I receive a standard domain prefixed pre-signed url and the upload works fine.

Other notes on my setup.

  1. I have configured the /upload resource on API Gateway to be an S3 passthrough for the PUT method.
  2. I have enabled CORS where needed. On the bucket and on my API. I have confirmed CORS is good, as the browser passes checks.
  3. I have setup my policies. The lambda function has access to the internet from my VPC, it has full S3 access, and it has a trust relationship with both S3 and API Gateway. This execution role is shared amongst the resources.
  4. I am using the axios package to upload the file via PUT.
  5. I have added a CloudTrail log, but it reports the exact same error as the browser...
  6. Temporarily making my bucket public makes no difference.
  7. I've attempted to add the query strings to the API Gateway Request/Response integrations without success.
  8. I've added the necessary content type headers to the request and to the pre-signed url config.
  9. I Googled the heck out of this thing.

Am I missing something? Is this possible? I plan to disable my custom endpoint and move forward with the default pre-signed url for the time being, but long term, I would like the custom endpoint. Worst case I may pay for some AWS support.

Thanks for the help!

Chris
  • 4,762
  • 3
  • 44
  • 79

1 Answers1

0

I can't find documentation that states a presigned URL supports proxy (alt/custom domain). IMO the use-case to authenticate and grant requests access to AWS resources from an API gateway ( regardless of if you are proxy'ing S3 ) would be to use an API Gateway authorizer w/lambda to allow the request to assume an IAM role that has access to the AWS resources (in this case PUT OBJECT on an s3 bucket)

https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html

John
  • 912
  • 6
  • 12
  • I am already using authorizers with lambda for my API. this particular process happens on the client side however, I would prefer not to expose my keys. If I route to my server first, then I am uploading the file twice. I also agree, this may not be supported. It let me get this far, so I was hoping I could go all the way. – Chris Sep 05 '18 at 20:26
  • @Chris - any luck? – joshblour Feb 06 '19 at 10:31