apostrophecms / apostrophecms/apostrophe

S3: uploads fail with AccessControlListNotSupported on buckets with BucketOwnerEnforced

Open Beginner friendly
#5,366 2 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
JavaScript
Stars
4.6k
Forks
650
Avg merge
19h 21m
Merged PRs (30d)
23

Description

## Problem

Since April 2023, AWS S3 creates all new buckets with `ObjectOwnership: BucketOwnerEnforced`
by default, which disables ACLs entirely. uploadfs always sends `ACL: 'public-read'`
(or whatever `bucketObjectsACL` is set to) in every `copyIn`, `enable`, and `disable` call,
causing all uploads to fail with:
```
AccessControlListNotSupported: The bucket does not allow ACLs
```

## Root Cause

In `lib/storage/s3.js`, the `ACL` param is always included in requests:
```js
// copyIn
const params = {
Bucket: bucket,
ACL: bucketObjectsACL, // always sent, no way to disable
...
};

// enable / disable also always call PutObjectAclCommand
```

## Expected Behavior

It should be possible to pass `bucketObjectsACL: false` (and `disabledBucketObjectsACL: false`)
to skip sending ACL headers entirely, for use with modern S3 buckets or S3-compatible
storage that does not support ACLs.

## Suggested Fix
```js
bucketObjectsACL = options.bucketObjectsACL === false
? false
: (options.bucketObjectsACL || 'public-read');

disabledBucketObjectsACL = options.disabledBucketObjectsACL === false
? false
: (options.disabledBucketObjectsACL || 'private');
```

Then in `copyIn`, `enable`, and `disable` — skip ACL if value is `false`.

This is fully backward compatible — existing users who don't set these options
get the same `public-read` default as before.

## Related

- AWS announcement: https://aws.amazon.com/blogs/aws/heads-up-amazon-s3-security-changes-are-coming-in-april-of-2023/

Contributor guide

Open the contributing guide

Research direction

Start in lib/storage/s3.js and inspect the copyIn, enable, and disable entry points, including how bucketObjectsACL and disabledBucketObjectsACL are initialized. Done means false prevents ACL parameters and PutObjectAclCommand calls while the existing default ACL behavior remains unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, javascript
Domain
backend, cloud
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.