Search code examples
amazon-web-servicesgoamazon-s3aws-sdkaws-sdk-go

AWS presigned url acl public read invalid signature


I have a private bucket, I want create a pre signed url that allows a user to upload a file to within the time limit and set the ACL to public read only.

When creating a PutObjectRequest like below it works fine I can PUT the file no problem. When I add ACL: aws.String("public-read"), I get the error 'signature doesn't match' and the PUT fails, here is a sample of the url the GO sdk is generating.

https://<MY-BUCKET>.s3.eu-west-2.amazonaws.com/<MY-KEY>?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=<AWS_ACCESS_KEY>/20170505/eu-west-2/s3/aws4_request&X-Amz-Date=20170505T793528Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host;x-amz-acl&X-Amz-Signature=2584062aaa76545665bfed7204fcf0dfe233a45016f698e7e8a11c34a5a7921e

I have tried with the root aws user and a normal user. I have tried with bucket policy and without, and with bucket policy and IAM policy of FULL S3 access and without. Basically all combinations. Any time I add the ACL field the signature error appears.

I am not sure if it's related to the GO SDK or to the AWS service. Can someone advice on what I am to do?

svc := s3.New(session.New(&aws.Config{Region: aws.String("eu-west-2")}))
    req, _ := svc.PutObjectRequest(&s3.PutObjectInput{
        ACL: aws.String("public-read"),
        Bucket: aws.String("MY BUCKET NAME"),
        Key:    aws.String("MY KEY"),
    })
    str, err := req.Presign(15 * time.Minute)

Solution

  • It was and error on the aws service end, the url is not being signed.