Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

‼️ NOTICE: new S3 Buckets trying to use ACLs fail to create if not explicitly opted in #25358

Closed
corymhall opened this issue Apr 28, 2023 · 14 comments
Labels
@aws-cdk/aws-s3 Related to Amazon S3 management/tracking Issues that track a subject or multiple issues

Comments

@corymhall
Copy link
Contributor

corymhall commented Apr 28, 2023

What is the issue?

Amazon S3 Buckets have a property called ObjectOwnership. 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

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:

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:

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:

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:

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

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.

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.

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. If you are providing your own logging bucket to CloudFront, then you need to make sure to set the ObjectOwnership property.

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.

@corymhall corymhall added the @aws-cdk/aws-s3 Related to Amazon S3 label Apr 28, 2023
@rix0rrr rix0rrr changed the title ‼️ NOTICE: S3 disables Access Control Lists (ACLs) by default for new Buckets ‼️ NOTICE: new S3 Buckets trying to use ACLs fail to create if not explicitly opted in Apr 28, 2023
@corymhall corymhall pinned this issue Apr 28, 2023
@tmokmss
Copy link
Contributor

tmokmss commented Apr 29, 2023

@corymhall Thank you for summarizing this problem!

NITS: I found the sentence If you meet the following then you should not be affected and can stop reading a bit misleading, because we do need to add the objectOwnership property for an S3 Bucket for CloudFront logs even in aws-cdk-lib >= 2.77.0, if we don't use a default bucket.

mergify bot pushed a commit to awslabs/cdk-serverless-clamscan that referenced this issue Apr 30, 2023
…S3 defaults (#812)

Related to aws/aws-cdk#25358
Resolves #806

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
rix0rrr added a commit to cdklabs/aws-cdk-notices that referenced this issue May 1, 2023
All CDK versions <2.60.0 are impacted (that's when we introduced
the feature flag).

Since we can't check on feature flags in the CLI notices, alert only
the definitely impacted crowd.
mergify bot pushed a commit to cdklabs/aws-cdk-notices that referenced this issue May 1, 2023
All CDK versions <2.60.0 are impacted (that's when we introduced the feature flag).

Since we can't check on feature flags in the CLI notices, alert only the definitely impacted crowd.

Fixes #
@peterwoodworth peterwoodworth added the management/tracking Issues that track a subject or multiple issues label May 2, 2023
@alexhddev
Copy link

Still failing with cdk 2.77. Tring to create a bucket with
accessControl: BucketAccessControl.PUBLIC_READ
but getting the error:
The bucket does not allow ACLs (Service: Amazon S3; Status Code: 400; Error Code: AccessControlListNotSupported

@corymhall
Copy link
Contributor Author

@alexhddev did you upgrade the version of aws-cdk-lib to 2.77.0 (not just the CLI)?

@alexhddev
Copy link

@corymhall yes. Currenlty I solved the issue by using the blockPublicAccess option when creating the bucket:

            blockPublicAccess: {
                blockPublicAcls: false,
                blockPublicPolicy: false,
                ignorePublicAcls: false,
                restrictPublicBuckets: false
            }

@thekevshow
Copy link

thekevshow commented May 4, 2023

@corymhall yes. Currenlty I solved the issue by using the blockPublicAccess option when creating the bucket:

            blockPublicAccess: {
                blockPublicAcls: false,
                blockPublicPolicy: false,
                ignorePublicAcls: false,
                restrictPublicBuckets: false
            }

I had tried this and upgraded to what was JUST released today even after trying 77 and now on 78. Same errors when applying
accessControl: s3.BucketAccessControl.PUBLIC_READ,
objectOwnership: s3.ObjectOwnership.OBJECT_WRITER,

The only way I could even work around it was to deploy the bucket with the privacy settings configured, change them through console, even though they aren't configured from default there in the global settings. Then to redeploy with my cloudfront association to the bucket. Which there was no errors there.

This type of breakage with the CDK, with S3, which is considered something that is managed with stability, is honestly very frustrating and quite embarrassing. Wasted significant time reading everything that indicated there should not have been an issue with explicit settings defined, WITH an administrator access account even, to eliminate all other potential permission issues. That said, for anyone else running into this issue, you might as well save yourself the 3 hours of reading broken documentation until these bugs that are inevitably popping up because it only affects NEWLY created buckets, which will eventually resolved. Again, this was probably my most frustrating experience to date with CDK and AWS, and I have been using it since 2018, prior to version 1.0.0. We are now at version 2.0.0. These types of things really are, as I said, beyond frustrating.

^ Rant aside, with relevant info. If you are trying to save yourself time, follow the above ^.

EDIT:
Have to remove accessControl: s3.BucketAccessControl.PUBLIC_READ
and add

blockPublicAccess: {
                blockPublicAcls: false,
                blockPublicPolicy: false,
                ignorePublicAcls: false,
                restrictPublicBuckets: false
            }

for this to work. I also assume publicReadAccess: true potentially as well.

@corymhall
Copy link
Contributor Author

@thekevshow are you saying that this configuration will not work?

new s3.Bucket(this, 'Bucket', {
  blockPublicAccess: {
    blockPublicAcls: false,
    blockPublicPolicy: false,
    ignorePublicAcls: false,
    restrictPublicBuckets: false
  },
  accessControl: s3.BucketAccessControl.PUBLIC_READ,
  objectOwnership: s3.ObjectOwnership.OBJECT_WRITER,
})

@danielesalvatore
Copy link

For the time being, I managed to solve the issue overriding the S3 resource property like the below:

bucket = aws_s3.Bucket(...)

# PublicAccessBlockConfiguration.BlockPublicPolicy property override
s3_resource = bucket.node.default_child
s3_resource.add_override("Properties.PublicAccessBlockConfiguration.BlockPublicPolicy", "False")

joostvanderborg added a commit to GemeenteNijmegen/tribe-brp-linker that referenced this issue May 8, 2023
In https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/AccessLogs.html
it's described how since april 2023, new bucket are created with ACLs
disabled. Cloudfront still requires them, so it needs to be set.

In aws/aws-cdk#25358, specifically under
'Using an S3 Bucket for CloudFront logs' there's a solution posted. This
implements that option, to prevent the cloudformation error:
""Invalid request provided: AWS::CloudFront::Distribution: The S3 bucket
that you specified for CloudFront logs does not enable ACL access"
@khushail khushail unpinned this issue May 8, 2023
@corymhall corymhall pinned this issue May 16, 2023
@rix0rrr rix0rrr closed this as completed May 26, 2023
@github-actions
Copy link

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

@0xdevalias
Copy link
Contributor

0xdevalias commented Jun 15, 2023

Edit: Created the following issue to re-track this bug + suggested ways of improving the CDK to prevent this issue properly:


I'm running into what I think is this same issue currently:

CREATE_FAILED        | AWS::S3::BucketPolicy                | SiteBucketPolicy3AC1D0F8
API: s3:PutBucketPolicy Access Denied

Which also seems to correspond with the issues described (and solved) on this Reddit thread:

My CDK code looks like this:

const siteBucket = new Bucket(this, 'SiteBucket', {
  bucketName: appDomain,
  websiteIndexDocument: 'index.html',
  websiteErrorDocument: 'error.html',
  publicReadAccess: true,
  cors: [
    {
      allowedOrigins: ['*'],
      allowedMethods: [HttpMethods.GET],
    },
  ],

  // The default removal policy is RETAIN, which means that cdk destroy will not attempt to delete
  // the new bucket, and it will remain in your account until manually deleted. By setting the policy to
  // DESTROY, cdk destroy will attempt to delete the bucket, but will error if the bucket is not empty.
  removalPolicy: RemovalPolicy.DESTROY, // NOT recommended for production code
})

// ..snip..

const distribution = new CloudFrontWebDistribution(
  this,
  'SiteDistribution',
  {
    viewerCertificate: {
      aliases: [appDomain],
      props: {
        acmCertificateArn: certificate.certificateArn,
        sslSupportMethod: SSLMethod.SNI,
        minimumProtocolVersion: SecurityPolicyProtocol.TLS_V1_1_2016,
      },
    },
    viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
    originConfigs: [
      {
        s3OriginSource: {
          s3BucketSource: siteBucket,
        },
        behaviors: [{ isDefaultBehavior: true }],
      },
    ],
    errorConfigurations: [
      {
        errorCode: 403,
        responseCode: 200,
        responsePagePath: '/index.html',
      },
      {
        errorCode: 404,
        responseCode: 200,
        responsePagePath: '/index.html',
      },
    ],
  }
)

// ..snip..

new BucketDeployment(this, 'Deploy', {
  sources: [
    Source.asset('../REDACTED1'),
    Source.asset('../REDACTED2'),
  ],
  destinationBucket: siteBucket,
  distribution,
  distributionPaths: ['/*'],
})

Focussing in on the Bucket, we can see that it has the publicReadAccess property set to true:

const siteBucket = new Bucket(this, 'SiteBucket', {
  // ..snip..
  publicReadAccess: true,
  // ..snip..
})

Using cdk synth with publicReadAccess set to true/false and diffing the results produces the following (where the SiteBucketPolicy3AC1D0F8 is added when publicReadAccess is true):

--- Resources:
+++ Resources:
@@ -32,6 +32,27 @@
     DeletionPolicy: Delete
     Metadata:
       aws:cdk:path: REDACTED/SiteBucket/Resource
+  SiteBucketPolicy3AC1D0F8:
+    Type: AWS::S3::BucketPolicy
+    Properties:
+      Bucket:
+        Ref: SiteBucket397A1860
+      PolicyDocument:
+        Statement:
+          - Action: s3:GetObject
+            Effect: Allow
+            Principal:
+              AWS: "*"
+            Resource:
+              Fn::Join:
+                - ""
+                - - Fn::GetAtt:
+                      - SiteBucket397A1860
+                      - Arn
+                  - /*
+        Version: "2012-10-17"
+    Metadata:
+      aws:cdk:path: REDACTED/SiteBucket/Policy/Resource
   SiteDistributionCFDistribution209CF7F5:
     Type: AWS::CloudFront::Distribution
     Properties:

Given this seems to be incompatible with the new defaults on AWS, I would expect that this should do some measure of:

  • Throw a TypeScript error as a disallowed combination of keys
  • Throw an actual runtime error + explain how to resolve it
  • Automagically set/default the underlying permissions/control policies/etc so that the code continues to 'just work' as expected; without needing to know the depths and intrinsic relations of the various settings to one another

See Also

@Aarbel
Copy link

Aarbel commented Jun 27, 2023

Same problem here.

Does someone has a working solution to deploy a public S3 bucket with CDK ?

@Aarbel
Copy link

Aarbel commented Jun 27, 2023

@corymhall

Did it work on your side ?

new s3.Bucket(this, 'Bucket', {
  blockPublicAccess: {
    blockPublicAcls: false,
    blockPublicPolicy: false,
    ignorePublicAcls: false,
    restrictPublicBuckets: false
  },
  accessControl: s3.BucketAccessControl.PUBLIC_READ,
  objectOwnership: s3.ObjectOwnership.OBJECT_WRITER,
})

@0xdevalias
Copy link
Contributor

0xdevalias commented Jun 28, 2023

Does someone has a working solution to deploy a public S3 bucket with CDK ?

@Aarbel Did you look at the stuff in #25983 ?

Eg. From the background research I did on that issue, I linked to this PR:

Which seemed to just be able to add objectOwnership: s3.ObjectOwnership.OBJECT_WRITER,

So I suspect the solution may be as simple as:

new s3.Bucket(this, 'Bucket', {
  publicReadAccess: true,
  objectOwnership: s3.ObjectOwnership.OBJECT_WRITER,
})

But I haven't explicitly tested it.

That's also based on this:

Which to me, implies that just explicitly setting objectOwnership to the old default of s3.ObjectOwnership.OBJECT_WRITER sounds like it should restore the previous functionality.

We can see here that parseOwnershipControls will automatically set objectOwnership to OBJECT_WRITER when accessControl is set to a value that requires it:

  • private parseOwnershipControls(): CfnBucket.OwnershipControlsProperty | undefined {
    // Enabling an ACL explicitly is required for all new buckets.
    // https://aws.amazon.com/about-aws/whats-new/2022/12/amazon-s3-automatically-enable-block-public-access-disable-access-control-lists-buckets-april-2023/
    const aclsThatDoNotRequireObjectOwnership = [
    BucketAccessControl.PRIVATE,
    BucketAccessControl.BUCKET_OWNER_READ,
    BucketAccessControl.BUCKET_OWNER_FULL_CONTROL,
    ];
    const accessControlRequiresObjectOwnership = (this.accessControl && !aclsThatDoNotRequireObjectOwnership.includes(this.accessControl));
    if (!this.objectOwnership && !accessControlRequiresObjectOwnership) {
    return undefined;
    }
    if (accessControlRequiresObjectOwnership && this.objectOwnership === ObjectOwnership.BUCKET_OWNER_ENFORCED) {
    throw new Error (`objectOwnership must be set to "${ObjectOwnership.OBJECT_WRITER}" when accessControl is "${this.accessControl}"`);
    }
    return {
    rules: [{
    objectOwnership: this.objectOwnership ?? ObjectOwnership.OBJECT_WRITER,
    }],
    };
    }

Though if that doesn't work, then this Reddit answer suggests this:

const bucket = new s3.Bucket(this, 'WebsiteBucket', {
  // your other bucket configurations
  publicReadAccess: true,
  blockPublicAccess: new s3.BlockPublicAccess({
    blockPublicAcls: false,
    ignorePublicAcls: false,
    blockPublicPolicy: false,
    restrictPublicBuckets: false,
  }),

We can see what each of the blockPublicAccess items does here:


Edit: To add some more 'concrete evidence' (rather than assumptions) of what each of these options does (on CDK 2.84.0), here are the relevant outputs for each from cdk synth. Diff highlighting based on difference from 'Option 1':

Option 1:

new Bucket(this, 'TestPublicBucket', {
  publicReadAccess: true,
})
TestPublicBucket87623E53:
  Type: AWS::S3::Bucket
  UpdateReplacePolicy: Retain
  DeletionPolicy: Retain
  Metadata:
    aws:cdk:path: REDACTED/TestPublicBucket/Resource
TestPublicBucketPolicyB64BAA28:
  Type: AWS::S3::BucketPolicy
  Properties:
    Bucket:
      Ref: TestPublicBucket87623E53
    PolicyDocument:
      Statement:
        - Action: s3:GetObject
          Effect: Allow
          Principal:
            AWS: "*"
          Resource:
            Fn::Join:
              - ""
              - - Fn::GetAtt:
                    - TestPublicBucket87623E53
                    - Arn
                - /*
      Version: "2012-10-17"
  Metadata:
    aws:cdk:path: REDACTED/TestPublicBucket/Policy/Resource

Option 2:

new Bucket(this, 'TestPublicBucket', {
  publicReadAccess: true,
+ objectOwnership: ObjectOwnership.OBJECT_WRITER,
})
TestPublicBucket87623E53:
  Type: AWS::S3::Bucket
+ Properties:
+   OwnershipControls:
+     Rules:
+       - ObjectOwnership: ObjectWriter
  UpdateReplacePolicy: Retain
  DeletionPolicy: Retain
  Metadata:
    aws:cdk:path: REDACTED/TestPublicBucket/Resource
TestPublicBucketPolicyB64BAA28:
  Type: AWS::S3::BucketPolicy
  Properties:
    Bucket:
      Ref: TestPublicBucket87623E53
    PolicyDocument:
      Statement:
        - Action: s3:GetObject
          Effect: Allow
          Principal:
            AWS: "*"
          Resource:
            Fn::Join:
              - ""
              - - Fn::GetAtt:
                    - TestPublicBucket87623E53
                    - Arn
                - /*
      Version: "2012-10-17"
  Metadata:
    aws:cdk:path: REDACTED/TestPublicBucket/Policy/Resource

Option 3:

new Bucket(this, 'TestPublicBucket', {
  publicReadAccess: true,
+ blockPublicAccess: new BlockPublicAccess({
+   blockPublicAcls: false,
+   ignorePublicAcls: false,
+   blockPublicPolicy: false,
+   restrictPublicBuckets: false,
+ }),
})
TestPublicBucket87623E53:
  Type: AWS::S3::Bucket
+ Properties:
+   PublicAccessBlockConfiguration:
+     BlockPublicAcls: false
+     BlockPublicPolicy: false
+     IgnorePublicAcls: false
+     RestrictPublicBuckets: false
  UpdateReplacePolicy: Retain
  DeletionPolicy: Retain
  Metadata:
    aws:cdk:path: REDACTED/TestPublicBucket/Resource
TestPublicBucketPolicyB64BAA28:
  Type: AWS::S3::BucketPolicy
  Properties:
    Bucket:
      Ref: TestPublicBucket87623E53
    PolicyDocument:
      Statement:
        - Action: s3:GetObject
          Effect: Allow
          Principal:
            AWS: "*"
          Resource:
            Fn::Join:
              - ""
              - - Fn::GetAtt:
                    - TestPublicBucket87623E53
                    - Arn
                - /*
      Version: "2012-10-17"
  Metadata:
    aws:cdk:path: REDACTED/TestPublicBucket/Policy/Resource

Option 4:

new Bucket(this, 'TestPublicBucket', {
- publicReadAccess: true,
+ blockPublicAccess: {
+   blockPublicAcls: false,
+   ignorePublicAcls: false,
+   blockPublicPolicy: false,
+   restrictPublicBuckets: false,
+ },
+ accessControl: BucketAccessControl.PUBLIC_READ,
})
TestPublicBucket87623E53:
  Type: AWS::S3::Bucket
+ Properties:
+   AccessControl: PublicRead
+   OwnershipControls:
+     Rules:
+       - ObjectOwnership: ObjectWriter
+   PublicAccessBlockConfiguration:
+     BlockPublicAcls: false
+     BlockPublicPolicy: false
+     IgnorePublicAcls: false
+     RestrictPublicBuckets: false
  UpdateReplacePolicy: Retain
  DeletionPolicy: Retain
  Metadata:
    aws:cdk:path: REDACTED/TestPublicBucket/Resource
-TestPublicBucketPolicyB64BAA28:
-  Type: AWS::S3::BucketPolicy
-  Properties:
-    Bucket:
-      Ref: TestPublicBucket87623E53
-    PolicyDocument:
-      Statement:
-        - Action: s3:GetObject
-          Effect: Allow
-          Principal:
-            AWS: "*"
-          Resource:
-            Fn::Join:
-              - ""
-              - - Fn::GetAtt:
-                    - TestPublicBucket87623E53
-                    - Arn
-                - /*
-      Version: "2012-10-17"

Option 5:

new Bucket(this, 'TestPublicBucket', {
- publicReadAccess: true,
+ blockPublicAccess: {
+   blockPublicAcls: false,
+   ignorePublicAcls: false,
+   blockPublicPolicy: false,
+   restrictPublicBuckets: false,
+ },
+ accessControl: BucketAccessControl.PUBLIC_READ,
+ objectOwnership: ObjectOwnership.OBJECT_WRITER,
})
TestPublicBucket87623E53:
  Type: AWS::S3::Bucket
+ Properties:
+   AccessControl: PublicRead
+   OwnershipControls:
+     Rules:
+       - ObjectOwnership: ObjectWriter
+   PublicAccessBlockConfiguration:
+     BlockPublicAcls: false
+     BlockPublicPolicy: false
+     IgnorePublicAcls: false
+     RestrictPublicBuckets: false
  UpdateReplacePolicy: Retain
  DeletionPolicy: Retain
  Metadata:
    aws:cdk:path: REDACTED/TestPublicBucket/Resource
-TestPublicBucketPolicyB64BAA28:
-  Type: AWS::S3::BucketPolicy
-  Properties:
-    Bucket:
-      Ref: TestPublicBucket87623E53
-    PolicyDocument:
-      Statement:
-        - Action: s3:GetObject
-          Effect: Allow
-          Principal:
-            AWS: "*"
-          Resource:
-            Fn::Join:
-              - ""
-              - - Fn::GetAtt:
-                    - TestPublicBucket87623E53
-                    - Arn
-                - /*
-      Version: "2012-10-17"

Option 6:

new Bucket(this, 'TestPublicBucket', {
  publicReadAccess: true,
+ blockPublicAccess: {
+   blockPublicAcls: false,
+   ignorePublicAcls: false,
+   blockPublicPolicy: false,
+   restrictPublicBuckets: false,
+ },
+ accessControl: BucketAccessControl.PUBLIC_READ,
+ objectOwnership: ObjectOwnership.OBJECT_WRITER,
})
TestPublicBucket87623E53:
  Type: AWS::S3::Bucket
+ Properties:
+   AccessControl: PublicRead
+   OwnershipControls:
+     Rules:
+       - ObjectOwnership: ObjectWriter
+   PublicAccessBlockConfiguration:
+     BlockPublicAcls: false
+     BlockPublicPolicy: false
+     IgnorePublicAcls: false
+     RestrictPublicBuckets: false
  UpdateReplacePolicy: Retain
  DeletionPolicy: Retain
  Metadata:
    aws:cdk:path: REDACTED/TestPublicBucket/Resource
TestPublicBucketPolicyB64BAA28:
  Type: AWS::S3::BucketPolicy
  Properties:
    Bucket:
      Ref: TestPublicBucket87623E53
    PolicyDocument:
      Statement:
        - Action: s3:GetObject
          Effect: Allow
          Principal:
            AWS: "*"
          Resource:
            Fn::Join:
              - ""
              - - Fn::GetAtt:
                    - TestPublicBucket87623E53
                    - Arn
                - /*
      Version: "2012-10-17"
  Metadata:
    aws:cdk:path: REDACTED/TestPublicBucket/Policy/Resource

Based on the above, I think the full command (until #25983 is fixed) might actually be:

new Bucket(this, 'TestPublicBucket', {
  publicReadAccess: true,
  blockPublicAccess: {
    blockPublicAcls: false,
    ignorePublicAcls: false,
    blockPublicPolicy: false,
    restrictPublicBuckets: false,
  },
  accessControl: BucketAccessControl.PUBLIC_READ,
  objectOwnership: ObjectOwnership.OBJECT_WRITER,
})

Though due to the helpers already implemented in parseOwnershipControls, I think we can currently drop objectOwnership and so probably get away with just:

new Bucket(this, 'TestPublicBucket', {
  publicReadAccess: true,
  blockPublicAccess: {
    blockPublicAcls: false,
    ignorePublicAcls: false,
    blockPublicPolicy: false,
    restrictPublicBuckets: false,
  },
  accessControl: BucketAccessControl.PUBLIC_READ,
})

@Aarbel Can you give that a go and see how it works for you?

@0xdevalias
Copy link
Contributor

For anybody who finds this issue, here what worked for us with cdk 2.83.1:

Example

bucket.grantWrite(workerNodejsFunction);
bucket.grantPutAcl(workerNodejsFunction);
  • Define well bucket props to force Acl (legacy) use

Example

    this.publicAssetsBucket = new s3.Bucket(
      this,
      "myBucket",
      {
        blockPublicAccess: new s3.BlockPublicAccess({
          blockPublicAcls: false,
          blockPublicPolicy: false,
          ignorePublicAcls: false,
          restrictPublicBuckets: false,
        }),
        objectOwnership: s3.ObjectOwnership.OBJECT_WRITER,
        ...
      }
    );

Originally posted by @Aarbel in #25983 (comment)

@rix0rrr rix0rrr unpinned this issue Jul 10, 2023
@Cheaterman
Copy link

Cheaterman commented Jul 11, 2023

Though due to the helpers already implemented in parseOwnershipControls, I think we can currently drop objectOwnership and so probably get away with just:

Nope, fails with Bucket cannot have ACLs set with ObjectOwnership's BucketOwnerEnforced setting (Service: Amazon S3; Status Code: 400; Error Code: InvalidBucketAclWithObjectOwnership;

I'm trying with both accessControl and objectOwnership right now, dunno if accessControl is needed (see above) but I'm getting very frustrated after trying 5 different solutions and I sure hope it'll work this time.

(... later)

It didn't work, I think the solution above might be the correct one (and the minimum necessary), one should not set accessControl. I think.

EDIT: And I thought wrong. Fails with API: s3:PutBucketPolicy Access Denied - we went full circle.

jpduckwo pushed a commit to jpduckwo/cdk-serverless-clamscan that referenced this issue Sep 4, 2023
…S3 defaults (awslabs#812)

Related to aws/aws-cdk#25358
Resolves awslabs#806

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
douglasnaphas added a commit to douglasnaphas/madliberation that referenced this issue Feb 4, 2024
Now ACLs aren't enabled by default in logging buckets.

So I need to specify the ACL settings myself.

I don't know the right ACL settings for CloudFront distro logging
buckets.

But enableLogging: true creates a bucket for me.

aws/aws-cdk#25358
https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_cloudfront-readme.html#logging
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-s3 Related to Amazon S3 management/tracking Issues that track a subject or multiple issues
Projects
None yet
Development

No branches or pull requests

10 participants