# s3:PutBucketPolicy Access Denied

**URL:** <https://forum.serverless.com/t/s3-putbucketpolicy-access-denied/18870>\
**Category:** Serverless Architectures\
**Tags:** aws, iam\
**Created:** [May 21, 2023, 12:12am UTC](https://forum.serverless.com/t/s3-putbucketpolicy-access-denied/18870 "2023-05-21T00:12:51Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![nirgluzman](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.serverless.com/nirgluzman/32/7476_2.png) [@nirgluzman](https://forum.serverless.com/u/nirgluzman)\
**Post date:** [May 21, 2023, 12:12am UTC](https://forum.serverless.com/t/s3-putbucketpolicy-access-denied/18870/1 "2023-05-21T00:12:51Z")

</div>

Hi,

I am following the guidelines to create S3 bucket which is served via CloudFront.  
S3 bucket does not need a public access, as the content is served from CloudFront.

> <https://github.com/serverless/examples/blob/master/aws-node-single-page-app-via-cloudfront/serverless.yml>

It seems that CloudFormation does not have the permission to generate the required S3 policy.  
Due to that, I receive the following error:

```auto
CREATE_FAILED: S3AccessPolicy (AWS::S3::BucketPolicy)
API: s3:PutBucketPolicy Access Denied

```

Could it be related to the following:

> <https://github.com/aws/aws-cdk/issues/25358>
>
> \## 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\`.

serverless.yml

```auto
resources:
  Resources:
    ## Specifying the S3 Bucket
    ReactAppBucket:
      Type: AWS::S3::Bucket
      Properties:
        BucketName: ${self:custom.bucketName}
        WebsiteConfiguration:
          IndexDocument: index.html
          ErrorDocument: index.html
    ## Specifying the policies to make sure all files inside the Bucket are avaialble to CloudFront
    S3AccessPolicy:
      Type: AWS::S3::BucketPolicy
      Properties:
        Bucket:
          Ref: ReactAppBucket
        PolicyDocument:
          Statement:
            - Sid: PublicReadGetObject
              Effect: Allow
              Principal: '*'
              Action:
                - s3:GetObject
              Resource: arn:aws:s3:::${self:custom.bucketName}/*
            - Sid: AllowPutBucketPolicy
              Effect: Allow
              Principal: '*'
              Action:
                - s3:PutBucketPolicy
              Resource: arn:aws:s3:::${self:custom.bucketName}

```

---

<div class="post-metadata">

**Author:** ![dnicolson](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.serverless.com/dnicolson/32/7484_2.png) [@dnicolson](https://forum.serverless.com/u/dnicolson)\
**Post date:** [May 27, 2023, 12:33pm UTC](https://forum.serverless.com/t/s3-putbucketpolicy-access-denied/18870/2 "2023-05-27T12:33:56Z")

</div>

AWS made changes to S3 bucket access, I created a pull request updating the example:

> <https://github.com/serverless/examples/pull/758>
>
> This pull request forces S3 buckets to be private otherwise the deployment fails…, see https://stackoverflow.com/a/76102067/2693925.

---

<div class="post-metadata">

**Author:** ![JoseLuis11](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.serverless.com/joseluis11/32/7500_2.png) [@JoseLuis11](https://forum.serverless.com/u/JoseLuis11)\
**Post date:** [June 3, 2023, 9:10pm UTC](https://forum.serverless.com/t/s3-putbucketpolicy-access-denied/18870/3 "2023-06-03T21:10:00Z")

</div>

Do you know how I can configure this but without using CloudFront?

I’m having the same exact error but I am not using CloudFront and I know it has to do with the **BlockPublicPolicy** now as default for new S3 Buckets, but I don’t know how to configure that in my serverless node.js project.

---

<div class="post-metadata">

**Author:** ![nirgluzman](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.serverless.com/nirgluzman/32/7476_2.png) [@nirgluzman](https://forum.serverless.com/u/nirgluzman)\
**Post date:** [June 3, 2023, 9:33pm UTC](https://forum.serverless.com/t/s3-putbucketpolicy-access-denied/18870/4 "2023-06-03T21:33:34Z")

</div>

> [@JoseLuis11](#):
>
> **BlockPublicPolicy**

Check this link:  
[AWS::S3::Bucket (examples)](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket.html#aws-properties-s3-bucket--examples)

Here are the settings I am using:

```auto
resources:
  Resources:
    ImageUploadBucket:
      Type: AWS::S3::Bucket
      Properties:
        BucketName: ${self:custom.imageUploadBucket}

        # Granting public access to bucket
        PublicAccessBlockConfiguration:
          BlockPublicAcls: false
          BlockPublicPolicy: false
          IgnorePublicAcls: false
          RestrictPublicBuckets: false

    ImageUploadBucketPolicy:
      Type: AWS::S3::BucketPolicy
      Properties:
        Bucket: !Ref ImageUploadBucket
        PolicyDocument:
          Version: '2008-10-17'
          Statement:
            - Sid: AllowPublicReadAccess
              Effect: Allow
              Principal: '*'
              Action: 's3:GetObject'
              Resource: arn:aws:s3:::${self:custom.imageUploadBucket}/*
              Condition:
                Bool:
                  aws:SecureTransport: 'true' # https://repost.aws/knowledge-center/s3-bucket-policy-for-config-rule

```

---

<div class="post-metadata">

**Author:** ![zulbil](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.serverless.com/zulbil/32/7648_2.png) [@zulbil](https://forum.serverless.com/u/zulbil)\
**Post date:** [September 14, 2023, 5:03pm UTC](https://forum.serverless.com/t/s3-putbucketpolicy-access-denied/18870/5 "2023-09-14T17:03:37Z")

</div>

Just to complete what you mentionned which is true, here’s a blog post i wrote regarding that issue named [How to solve the “api:s3:putbucketpolicy access denied” Error](https://joelalexandrekhang.com/post/how-to-solve-the-apis3putbucketpolicy-access-denied-error/).
