1

I have a use case to keep the AWS S3 Bucket Private as default but,
Make certain objects Public while uploading to AWS S3.

I am using the following code to sign the AWS S3 url using and ACL setting as public-read -

module.exports.generateS3PostSignedUrl = async (bucketName, bucketKey, objectExpiry) => {

    let s3Client = new AWS.S3({
        region: 'some-region'
    });

    let signingParams = {
        Expires: objectExpiry,
        Bucket: bucketName,
        Fields: {
            key: bucketKey,
        },
        Conditions: [
            ['acl', 'public-read']   
        ],
        ACL: 'public-read'
    }

    let s3createPresignedPost = util.promisify(s3Client.createPresignedPost).bind(s3Client);
    let signedUrl = await s3createPresignedPost(signingParams);

    return signedUrl;
};

Request while uploading -

enter image description here

I am able to upload the file to AWS S3, if I remove the conditions array in signing params,
but the file is still not public when I click its url.
I believe I have done something wrong code on signingParams part.


Ref -
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#createPresignedPost-property

Upload file to s3 with POST

Ani
  • 4,294
  • 16
  • 78
  • 133
  • did you try creating a signed url for getting the file, or are u trying a non signed url? – Vipul Dessai Dec 26 '19 at 05:34
  • I tried getting the object from Console by clicking the `Object URL` link, If I make it Public from console it opens else, returns an xml error, need to achieve the Make Public while uploading to S3 – Ani Dec 26 '19 at 05:35
  • no need to make it public, creating a signed url should do the trick – Vipul Dessai Dec 26 '19 at 05:38
  • and you are not creating a IAM user with access keys to write the file? – Vipul Dessai Dec 26 '19 at 05:39
  • no signed url involved for getting the object, the plan is to use the bucket prefix and the file name to view the public object – Ani Dec 26 '19 at 05:40
  • I am using an IAM Role to generate the createPresignedPost url – Ani Dec 26 '19 at 05:42
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/204860/discussion-between-vipul-dessai-and-aniruddha-raje). – Vipul Dessai Dec 26 '19 at 07:05
  • I suspect you also need to specify the ACL when performing the upload, not just in the signed portion. – John Rotenstein Dec 26 '19 at 08:38
  • @JohnRotenstein Any way to control from backend? Cause Frontend is out of server control while the browser js code uploads using the signed url – Ani Dec 26 '19 at 08:40
  • What you get? when you do get Object? from the code itself? – Saikat Chakrabortty Dec 26 '19 at 12:28
  • The frontend has the bucket name and prefix stored, we just change the image names to get the objects. – Ani Dec 26 '19 at 12:30

1 Answers1

1

The order of parameters matters here. Put acl parameter before the file and it should work; otherwise S3 just ignores the value you provided.

Below are the example screenshots with different placement of parameters in form-data.

Also, be sure to give execute the createPresignedPost by a user with s3:PutObjectAcl and s3:PutObject permissions.

The correct order of form-data parameters

The same request but with acl parameter being placed after file (Ignored by S3)

Rinoir
  • 11
  • 4
  • You mean while signing the URL? Or while uploading? Can you post the correct script? – Ani Feb 05 '20 at 03:10
  • @Ani I meant the uploading part. Updated my answer with a bit more details and my requests screenshots. Please take a look at those – Rinoir Feb 05 '20 at 09:54