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

fix(s3): updating blockPublicAccess to enable default true settings (under feature flag) #33702

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

IkeNefcy
Copy link
Contributor

@IkeNefcy IkeNefcy commented Mar 6, 2025

V3 but I think we got there

Issue

Closes #32811

Reason for this change

By default when you create an s3 bucket, all public access is already blocked. However if you then use CDK to specify 1 or more access point you want to unblock, all undefined block types will be auto set to false, and when it deploys you will see everything uncheck even if you only wanted to uncheck 1 thing.

So to fix this we should instead default all values to true when at least 1 option is specified, to mimic to experience when a user in the console unchecks the boxes.

Description of changes

deprecating BLOCK_ACLS method of BlockPublicAccess. Adding BLOCK_ACLS_ONLY.

  public static readonly BLOCK_ACLS_ONLY = new BlockPublicAccess({
    blockPublicAcls: true,
    blockPublicPolicy: false,
    ignorePublicAcls: true,
    restrictPublicBuckets: false,
  });

This is just a general revamp to match what the feature will bring, it's separate from the feature itself. The point being that for any shortcut methods like this, we should be specifying all 4 options to ensure the default true behavior remains.

Created function setBlockPublicAccessDefaults()

  /**
   * Function to set the blockPublicAccessOptions to a true default if not defined.
   * If no blockPublicAccessOptions are specified at all, this is already the case as an s3 default in aws
   * @see https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html
   */
  private setBlockPublicAccessDefaults(blockPublicAccessOptions: BlockPublicAccessOptions) {
    return {
      blockPublicAcls: blockPublicAccessOptions.blockPublicAcls ?? true,
      blockPublicPolicy: blockPublicAccessOptions.blockPublicPolicy ?? true,
      ignorePublicAcls: blockPublicAccessOptions.ignorePublicAcls ?? true,
      restrictPublicBuckets: blockPublicAccessOptions.restrictPublicBuckets ?? true,
    };
  }

but this method is only called if the FF is enabled

    let blockPublicAccess: BlockPublicAccessOptions | undefined = props.blockPublicAccess;
    if (props.blockPublicAccess && FeatureFlags.of(this).isEnabled(cxapi.S3_BLOCK_PUBLIC_ACCESS_OPTION_AUTO_TRUE)) {
      blockPublicAccess = this.setBlockPublicAccessDefaults(props.blockPublicAccess);
    }

Of course the FF itself was added.

The last few feature flags didn't have the big comment wall
//////////////////////////////////////////////////////////////////////
I like the big comment wall
//////////////////////////////////////////////////////////////////////
adding the big comment wall back
//////////////////////////////////////////:)//////////////////////////

Description of how you validated changes

Added tests that are duplicates of others, just testing for both behaviors with and without the FF.

  describe('bucket with custom block public access setting', () => {
    ...
    test('S3_BLOCK_PUBLIC_ACCESS_OPTION_AUTO_TRUE Enabled', () => {
      const app = new cdk.App({
        context: {
          [cxapi.S3_BLOCK_PUBLIC_ACCESS_OPTION_AUTO_TRUE]: true,
        },
      });
      const stack = new cdk.Stack(app);
      new s3.Bucket(stack, 'MyBucket', {
        blockPublicAccess: new s3.BlockPublicAccess({ restrictPublicBuckets: false }),
      });

      Template.fromStack(stack).templateMatches({
        'Resources': {
          'MyBucketF68F3FF0': {
            'Type': 'AWS::S3::Bucket',
            'Properties': {
              'PublicAccessBlockConfiguration': {
                'BlockPublicAcls': true,
                'BlockPublicPolicy': true,
                'IgnorePublicAcls': true,
                'RestrictPublicBuckets': false,
              },
            },
            'DeletionPolicy': 'Retain',
            'UpdateReplacePolicy': 'Retain',
          },
        },
      });
    });
  describe('bucket with custom block public access setting', () => {
    ...
    test('S3_BLOCK_PUBLIC_ACCESS_OPTION_AUTO_TRUE Enabled', () => {
      const app = new cdk.App({
        context: {
          [cxapi.S3_BLOCK_PUBLIC_ACCESS_OPTION_AUTO_TRUE]: true,
        },
      });
      const stack = new cdk.Stack(app);
      new s3.Bucket(stack, 'MyBucket', {
        blockPublicAccess: new s3.BlockPublicAccess({ restrictPublicBuckets: false }),
      });

      Template.fromStack(stack).templateMatches({
        'Resources': {
          'MyBucketF68F3FF0': {
            'Type': 'AWS::S3::Bucket',
            'Properties': {
              'PublicAccessBlockConfiguration': {
                'BlockPublicAcls': true,
                'BlockPublicPolicy': true,
                'IgnorePublicAcls': true,
                'RestrictPublicBuckets': false,
              },
            },
            'DeletionPolicy': 'Retain',
            'UpdateReplacePolicy': 'Retain',
          },
        },
      });
    });

Also added an integ that just tests different combinations of the blocking.

import { IntegTest } from '@aws-cdk/integ-tests-alpha';
import { App, Stack } from 'aws-cdk-lib';
import { BlockPublicAccess, Bucket } from 'aws-cdk-lib/aws-s3';
import { S3_BLOCK_PUBLIC_ACCESS_OPTION_AUTO_TRUE } from 'aws-cdk-lib/cx-api';
const app = new App({
context: {
[S3_BLOCK_PUBLIC_ACCESS_OPTION_AUTO_TRUE]: true,
},
});
const stack = new Stack(app, 'aws-cdk-s3-bucket-block-access');
new Bucket(stack, 'blockAcls', {
blockPublicAccess: BlockPublicAccess.BLOCK_ACLS,
});
new Bucket(stack, 'blockAclsOnly', {
blockPublicAccess: BlockPublicAccess.BLOCK_ACLS_ONLY,
});
new Bucket(stack, 'blockAll', {
blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
});
// in the next 2 tests, because not all 4 options are blocked, those left undefined should default to true
new Bucket(stack, 'blockOnly2', {
blockPublicAccess: new BlockPublicAccess({
blockPublicAcls: false,
blockPublicPolicy: false,
}),
});
new Bucket(stack, 'blockOnly1', {
blockPublicAccess: new BlockPublicAccess({
blockPublicPolicy: false,
}),
});
new IntegTest(app, 'testBlockingBucketAccess', {
testCases: [stack],
});

There was no BlockPublicAccess integ before so I did not add the context for the FF disabled anywhere. The tests should still be working since it's not used that often. But if the team needs me to, I can add a 2nd integ with the old behavior

Checklist


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

@github-actions github-actions bot added the repeat-contributor [Pilot] contributed between 3-5 PRs to the CDK label Mar 6, 2025
@aws-cdk-automation aws-cdk-automation requested a review from a team March 6, 2025 23:38
@github-actions github-actions bot added bug This issue is a bug. effort/small Small work item – less than a day of effort p2 labels Mar 6, 2025
Copy link

codecov bot commented Mar 6, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 82.37%. Comparing base (b48a5ad) to head (72af6aa).
Report is 8 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main   #33702   +/-   ##
=======================================
  Coverage   82.37%   82.37%           
=======================================
  Files         120      120           
  Lines        6933     6933           
  Branches     1169     1169           
=======================================
  Hits         5711     5711           
  Misses       1119     1119           
  Partials      103      103           
Flag Coverage Δ
suite.unit 82.37% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
packages/aws-cdk ∅ <ø> (∅)
packages/aws-cdk-lib/core 82.37% <ø> (ø)
🚀 New features to boost your workflow:
  • Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@IkeNefcy IkeNefcy marked this pull request as ready for review March 7, 2025 00:12
@aws-cdk-automation aws-cdk-automation added the pr/needs-community-review This PR needs a review from a Trusted Community Member or Core Team Member. label Mar 7, 2025
@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • CodeBuild project: AutoBuildv2Project1C6BFA3F-wQm2hXv2jqQv
  • Commit ID: 72af6aa
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue is a bug. effort/small Small work item – less than a day of effort p2 pr/needs-community-review This PR needs a review from a Trusted Community Member or Core Team Member. repeat-contributor [Pilot] contributed between 3-5 PRs to the CDK
Projects
None yet
Development

Successfully merging this pull request may close these issues.

aws-s3: blockPublicAccess has a counterintuitive behaviour
2 participants