aws nodejs sdk putObjectAcl correct syntax

1.3k Views Asked by At

I need to assign public read access and in the same time to allow owner to operate an object with full access after I process the object within the sharp() lib. So, I replace the old object with a new one and thus I need to set new ACL. The ACL allows to have only one type of access and I need kind of to combine "public-read" and "bucket-owner-full-controll"

According to the interface and documentation this is enough

await s3Bucket.putObjectAcl({
    Bucket: s3EventMessage.bucket.name,
    Key: key,
    AccessControlPolicy: {},
    GrantFullControl: 'canonical_id',
    GrantRead: 'http://acs.amazonaws.com/groups/global/AllUsers'
}).promise();

Also, I tried this, it should be enough according to the interface, but I'm getting errors:

    Bucket: s3EventMessage.bucket.name,
    Key: key,
    AccessControlPolicy: {
        Grants: [
            {
                Grantee: {
                    Type: "CanonicalUser"
                },
            },
        ],
    },
    GrantRead: 'http://acs.amazonaws.com/groups/global/AllUsers'

Also I tried this way, I get an error that my XML has wrong format

await s3Bucket.putObjectAcl({
    Bucket: s3EventMessage.bucket.name,
    Key: key,
    AccessControlPolicy: {
        Grants: [
            {
                Grantee: {
                    Type: "CanonicalUser",
                    DisplayName: 'Owner',
                    ID: 'canonical_id',
                },
                Permission: "FULL_CONTROL"
            },
            {
                Grantee: {
                    Type: "Group",
                    URI: 'http://acs.amazonaws.com/groups/global/AllUsers',
                },
                Permission: "READ",
            }
        ],
    },
}).promise();

The error:

MalformedACLError: The XML you provided was not well-formed or did not validate against our published schema

This syntax with a precise owner:

await s3Bucket.putObjectAcl({
    Bucket: s3EventMessage.bucket.name,
    Key: key,
    AccessControlPolicy: {
        Owner: {
            DisplayName: 'Owner',
            ID: 'canonical_id',
        },
        Grants: [
            {
                Grantee: {
                    Type: "CanonicalUser",
                    DisplayName: 'Owner',
                    ID: 'canonical_id',
                },
                Permission: "FULL_CONTROL"
            },
            {
                Grantee: {
                    Type: "Group",
                    URI: 'http://acs.amazonaws.com/groups/global/AllUsers',
                },
                Permission: "READ",
            }
        ],
    },
}).promise();

gives an error :

AccessDenied: Access Denied

also, I found a solution in PHP, but that didn't work for me - I'm getting access denied

this is the solution

this is the doc Nodejs example

Thanks in advance!

1

There are 1 best solutions below

0
On

After some investigation and playing around I figured out what I need:

  1. The lambda had to have a permission related to the bucket: s3:PutObject*
  2. This snippet works perfectly for my task:
    await s3Bucket.putObjectAcl({
        Bucket: bucket.name,
        Key: key,
        AccessControlPolicy: {
            Owner: {
                DisplayName: 'Owner',
                ID: 'canonical_id',
            },
            Grants: [
                {
                    Grantee: {
                        Type: "CanonicalUser",
                        DisplayName: 'Owner',
                        ID: 'canonical_id',
                    },
                    Permission: "FULL_CONTROL"
                },
                {
                    Grantee: {
                        Type: "Group",
                        URI: 'http://acs.amazonaws.com/groups/global/AllUsers',
                    },
                    Permission: "READ",
                }
            ],
        },
    }).promise();