## What is the issue?
Amazon S3 Buckets have a property called `ObjectOwnersh…ip`. It has 3 possible settings:
* `BucketOwnerEnforced`: access to all objects in the bucket is controlled via the bucket's Bucket Policy. Access Control Lists (ACLs) are disallowed, both on a per-object as well as bucket-wide level.
* `ObjectWriter`: ACLs are allowed, object writers decide the ACL for each object.
* `BucketOwnerPreferred`: ACLs are allowed, object writers can decide each object's ACL, but the default is to honor the Bucket Policy.
Before April 2023, the default was to create new buckets with `ObjectOwnership: ObjectWriter`, which means it is possible to configure ACLs on the buckets and on objects by default.
In April 2023, S3 has changed the default to `ObjectOwnership: BucketOwnerEnforced`, which means it is no longer possible to configure ACLs on the buckets and on objects by default.
Since this change affects only the defaults for new buckets, this change has no effect on existing S3 Buckets.
Announcement: [Amazon S3 will automatically enable S3 Block Public Access and disable access control lists for all new buckets starting in April 2023](https://aws.amazon.com/about-aws/whats-new/2022/12/amazon-s3-automatically-enable-block-public-access-disable-access-control-lists-buckets-april-2023/)
## What is the impact?
Depending on your CDK version and feature flags, CDK may try to configure buckets with an ACL, relying on the default `ObjectOwnership: ObjectWriter` for this to be allowed. After April 2023, buckets with ACLs will fail to deploy with the following error:
```text
Bucket cannot have ACLs set with ObjectOwnership's BucketOwnerEnforced setting
```
## What code is affected by this change?
**If you meet any of the following criteria then you are not affected and can stop reading:**
- You are using `aws-cdk-lib >= 2.60.0`, the feature flag `@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy: true` is set, and you are not using CloudFront logging; OR
- You are using `aws-cdk-lib >= 2.77.0`
Otherwise, keep on reading to find out what patterns may lead a bucket to fail creation. You could be affected if you use `aws-cdk-lib.aws_s3.Bucket` directly, or if you use a 3rd party construct library that creates S3 Buckets.
There are a couple of cases how a Bucket created by CDK may end up with an ACL configured on it. We will go over them here:
### Explicit bucket ACL
If you explicitly set the ACL to one of `PUBLIC_READ`, `AWS_EXEC_READ`, `PUBLIC_READ_WRITE`, `AUTHENTICATED_READ`, or `LOG_DELIVERY_WRITE`. Example:
```ts
new s3.Bucket(this, 'Bucket', {
accessControl: s3.BucketAccessControl.PUBLIC_READ,
});
```
### Using a serverAccessLogsBucket
If you set one bucket as the `serverAccessLogsBucket` of another, CDK automatically configures it with permissions for writing logs. Example:
```ts
const serverAccessLogsBucket = new s3.Bucket(this, 'AccessLogsBucket');
const sourceBucket = new s3.Bucket(this, 'Bucket', {
serverAccessLogsBucket,
});
```
If you are on a version `>= 2.60.0` and have the feature flag `@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy: true` configured, CDK will use a Bucket Policy for log writing permissions, and you are not affected.
Otherwise, it will use ACLs, and you are affected.
### Using an S3 Bucket for CloudFront logs
When you create a CloudFront Distribution with `enableLogging: true`, the CDK will automatically create a logging bucket for you that uses ACLs:
```ts
new cloudfront.Distribution(this, 'Distribution', {
enableLogging: true,
});
```
(If you are providing your own `logBucket`, you will fall into case 1, where you are explicitly configuring the bucket to use the log delivery ACL)
## How do I resolve this?
If you upgrade `aws-cdk-lib` to `>=2.77.0`, we will automatically set `ObjectOwnership` for you if you configure an ACL.
Only if you are not able to upgrade `aws-cdk-lib` quickly enough, see the instructions below for workarounds:
### Explicit ACL configuration
If you are explicitly setting the Bucket ACL then you need to now also explicitly set the ObjectOwnership to `OBJECT_WRITER`
```ts
new s3.Bucket(this, 'Bucket', {
accessControl: s3.BucketAccessControl.PUBLIC_READ,
objectOwnership: s3.ObjectOwnership.OBJECT_WRITER,
});
```
### Using a serverAccessLogsBucket
If configuring server access logs and you are on `aws-cdk-lib` `>=2.60.0 & <2.77.0` then set the `@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy` feature flag to true. This can be done either globally in the `cdk.json` file or on a per construct basis by using `setContext`.
```ts
class MyConstruct extends Construct {
constructor(scope: Construct, id: string) {
super(scope, id);
this.node.setContext('@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy', true);
const serverAccessLogsBucket = new s3.Bucket(this, 'AccessLogsBucket');
const sourceBucket = new s3.Bucket(this, 'Bucket', {
serverAccessLogsBucket,
});
}
```
If using CDK v1 or `aws-cdk-lib` `<2.60.0` then you have to configure ObjectOwnership directly.
```ts
const serverAccessLogsBucket = new s3.Bucket(this, 'AccessLogsBucket', {
objectOwnership: s3.ObjectOwnership.OBJECT_WRITER,
});
const sourceBucket = new s3.Bucket(this, 'Bucket', {
serverAccessLogsBucket,
});
```
### Using an S3 Bucket for CloudFront logs
[CloudFront logging still requires ACLs](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/AccessLogs.html#access-logs-choosing-s3-bucket). If you are providing your own logging bucket to CloudFront, then you need to make sure to set the `ObjectOwnership` property.
```ts
new cloudfront.Distribution(this, 'Distribution', {
logBucket: new s3.Bucket(this, 'Bucket', { objectOwnership: s3.ObjectOwnership.OBJECT_WRITER }),
});
```
If you are using `enableLogging: true` to have a bucket automatically created, you should upgrade to `2.77.0` to set the `ObjectOwnership` option correctly, or use escape hatches to force the option to `ObjectOwnership`.