diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.js.snapshot/aws-cdk-s3.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.js.snapshot/aws-cdk-s3.assets.json new file mode 100644 index 0000000000000..22e5d2ee65a10 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.js.snapshot/aws-cdk-s3.assets.json @@ -0,0 +1,19 @@ +{ + "version": "39.0.0", + "files": { + "c710c83a4c828b1352a3a7f312c8de69a8adeff3ce6e267a649a8e81e6351599": { + "source": { + "path": "aws-cdk-s3.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "c710c83a4c828b1352a3a7f312c8de69a8adeff3ce6e267a649a8e81e6351599.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.js.snapshot/aws-cdk-s3.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.js.snapshot/aws-cdk-s3.template.json new file mode 100644 index 0000000000000..e29da6867b22c --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.js.snapshot/aws-cdk-s3.template.json @@ -0,0 +1,69 @@ +{ + "Resources": { + "BucketWithDefaultAccessA1A49454": { + "Type": "AWS::S3::Bucket", + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "BucketWithExplicitBlockAccess67F3DE07": { + "Type": "AWS::S3::Bucket", + "Properties": { + "PublicAccessBlockConfiguration": { + "BlockPublicAcls": true, + "BlockPublicPolicy": true, + "IgnorePublicAcls": true, + "RestrictPublicBuckets": true + } + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "BucketWithPartialBlockAccessD49F8A59": { + "Type": "AWS::S3::Bucket", + "Properties": { + "PublicAccessBlockConfiguration": { + "BlockPublicAcls": true, + "BlockPublicPolicy": false, + "IgnorePublicAcls": true, + "RestrictPublicBuckets": false + } + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.js.snapshot/cdk.out new file mode 100644 index 0000000000000..91e1a8b9901d5 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"39.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.js.snapshot/cdkintegs3bucketblockpublicaccessDefaultTestDeployAssert2B4C2503.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.js.snapshot/cdkintegs3bucketblockpublicaccessDefaultTestDeployAssert2B4C2503.assets.json new file mode 100644 index 0000000000000..097fde47f6d19 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.js.snapshot/cdkintegs3bucketblockpublicaccessDefaultTestDeployAssert2B4C2503.assets.json @@ -0,0 +1,19 @@ +{ + "version": "39.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "cdkintegs3bucketblockpublicaccessDefaultTestDeployAssert2B4C2503.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.js.snapshot/cdkintegs3bucketblockpublicaccessDefaultTestDeployAssert2B4C2503.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.js.snapshot/cdkintegs3bucketblockpublicaccessDefaultTestDeployAssert2B4C2503.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.js.snapshot/cdkintegs3bucketblockpublicaccessDefaultTestDeployAssert2B4C2503.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.js.snapshot/integ.json new file mode 100644 index 0000000000000..d63a10f9cfe71 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "39.0.0", + "testCases": { + "cdk-integ-s3-bucket-block-public-access/DefaultTest": { + "stacks": [ + "aws-cdk-s3" + ], + "assertionStack": "cdk-integ-s3-bucket-block-public-access/DefaultTest/DeployAssert", + "assertionStackName": "cdkintegs3bucketblockpublicaccessDefaultTestDeployAssert2B4C2503" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.js.snapshot/manifest.json new file mode 100644 index 0000000000000..163b102fd1a0b --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.js.snapshot/manifest.json @@ -0,0 +1,125 @@ +{ + "version": "39.0.0", + "artifacts": { + "aws-cdk-s3.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "aws-cdk-s3.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "aws-cdk-s3": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "aws-cdk-s3.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/c710c83a4c828b1352a3a7f312c8de69a8adeff3ce6e267a649a8e81e6351599.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "aws-cdk-s3.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "aws-cdk-s3.assets" + ], + "metadata": { + "/aws-cdk-s3/BucketWithDefaultAccess/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "BucketWithDefaultAccessA1A49454" + } + ], + "/aws-cdk-s3/BucketWithExplicitBlockAccess/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "BucketWithExplicitBlockAccess67F3DE07" + } + ], + "/aws-cdk-s3/BucketWithPartialBlockAccess/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "BucketWithPartialBlockAccessD49F8A59" + } + ], + "/aws-cdk-s3/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-cdk-s3/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "aws-cdk-s3" + }, + "cdkintegs3bucketblockpublicaccessDefaultTestDeployAssert2B4C2503.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "cdkintegs3bucketblockpublicaccessDefaultTestDeployAssert2B4C2503.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "cdkintegs3bucketblockpublicaccessDefaultTestDeployAssert2B4C2503": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "cdkintegs3bucketblockpublicaccessDefaultTestDeployAssert2B4C2503.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "cdkintegs3bucketblockpublicaccessDefaultTestDeployAssert2B4C2503.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "cdkintegs3bucketblockpublicaccessDefaultTestDeployAssert2B4C2503.assets" + ], + "metadata": { + "/cdk-integ-s3-bucket-block-public-access/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/cdk-integ-s3-bucket-block-public-access/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "cdk-integ-s3-bucket-block-public-access/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.js.snapshot/tree.json new file mode 100644 index 0000000000000..312a5c4263eed --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.js.snapshot/tree.json @@ -0,0 +1,181 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "aws-cdk-s3": { + "id": "aws-cdk-s3", + "path": "aws-cdk-s3", + "children": { + "BucketWithDefaultAccess": { + "id": "BucketWithDefaultAccess", + "path": "aws-cdk-s3/BucketWithDefaultAccess", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-s3/BucketWithDefaultAccess/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::S3::Bucket", + "aws:cdk:cloudformation:props": {} + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.CfnBucket", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.Bucket", + "version": "0.0.0" + } + }, + "BucketWithExplicitBlockAccess": { + "id": "BucketWithExplicitBlockAccess", + "path": "aws-cdk-s3/BucketWithExplicitBlockAccess", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-s3/BucketWithExplicitBlockAccess/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::S3::Bucket", + "aws:cdk:cloudformation:props": { + "publicAccessBlockConfiguration": { + "blockPublicAcls": true, + "blockPublicPolicy": true, + "ignorePublicAcls": true, + "restrictPublicBuckets": true + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.CfnBucket", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.Bucket", + "version": "0.0.0" + } + }, + "BucketWithPartialBlockAccess": { + "id": "BucketWithPartialBlockAccess", + "path": "aws-cdk-s3/BucketWithPartialBlockAccess", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-s3/BucketWithPartialBlockAccess/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::S3::Bucket", + "aws:cdk:cloudformation:props": { + "publicAccessBlockConfiguration": { + "blockPublicAcls": true, + "blockPublicPolicy": false, + "ignorePublicAcls": true, + "restrictPublicBuckets": false + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.CfnBucket", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.Bucket", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-s3/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-s3/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "cdk-integ-s3-bucket-block-public-access": { + "id": "cdk-integ-s3-bucket-block-public-access", + "path": "cdk-integ-s3-bucket-block-public-access", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "cdk-integ-s3-bucket-block-public-access/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "cdk-integ-s3-bucket-block-public-access/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "cdk-integ-s3-bucket-block-public-access/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "cdk-integ-s3-bucket-block-public-access/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "cdk-integ-s3-bucket-block-public-access/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.ts new file mode 100644 index 0000000000000..a0c98686ae190 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket-block-public-access.ts @@ -0,0 +1,38 @@ +#!/usr/bin/env node +import * as cdk from 'aws-cdk-lib'; +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; +import * as s3 from 'aws-cdk-lib/aws-s3'; +import * as cxapi from 'aws-cdk-lib/cx-api'; + +const myFeatureFlag = { [cxapi.S3_BUCKET_DEFAULT_BLOCK_PUBLIC_ACCESS_PROPERTIES_TO_TRUE]: true }; + +const app = new cdk.App({ + context: myFeatureFlag, +}); + +const stack = new cdk.Stack(app, 'aws-cdk-s3'); + +// Bucket with default setting for `blockPublicAccess` +new s3.Bucket(stack, 'BucketWithDefaultAccess', {}); + +// Bucket with explicit setting for `blockPublicAccess` +new s3.Bucket(stack, 'BucketWithExplicitBlockAccess', { + blockPublicAccess: new s3.BlockPublicAccess({ + blockPublicAcls: true, + ignorePublicAcls: true, + blockPublicPolicy: true, + restrictPublicBuckets: true, + }), +}); + +// Bucket with partial setting for `blockPublicAccess` +new s3.Bucket(stack, 'BucketWithPartialBlockAccess', { + blockPublicAccess: new s3.BlockPublicAccess({ + blockPublicPolicy: false, + restrictPublicBuckets: false, + }), +}); + +new IntegTest(app, 'cdk-integ-s3-bucket-block-public-access', { + testCases: [stack], +}); diff --git a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts index 79034e4b891e0..e6327573ff423 100644 --- a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts +++ b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts @@ -35,6 +35,7 @@ import * as regionInformation from '../../region-info'; const AUTO_DELETE_OBJECTS_RESOURCE_TYPE = 'Custom::S3AutoDeleteObjects'; const AUTO_DELETE_OBJECTS_TAG = 'aws-cdk:auto-delete-objects'; +var s3BucketDefaultBlockPublicAccessPropertiesToTrueFeatureFlag: boolean = false; export interface IBucket extends IResource { /** @@ -1094,10 +1095,11 @@ export class BlockPublicAccess { public restrictPublicBuckets: boolean | undefined; constructor(options: BlockPublicAccessOptions) { - this.blockPublicAcls = options.blockPublicAcls; - this.blockPublicPolicy = options.blockPublicPolicy; - this.ignorePublicAcls = options.ignorePublicAcls; - this.restrictPublicBuckets = options.restrictPublicBuckets; + const defaultToTrue = s3BucketDefaultBlockPublicAccessPropertiesToTrueFeatureFlag; + this.blockPublicAcls = defaultToTrue ? options.blockPublicAcls ?? true : options.blockPublicAcls; + this.blockPublicPolicy = defaultToTrue ? options.blockPublicPolicy ?? true : options.blockPublicPolicy; + this.ignorePublicAcls = defaultToTrue ? options.ignorePublicAcls ?? true : options.ignorePublicAcls; + this.restrictPublicBuckets = defaultToTrue ? options.restrictPublicBuckets ?? true : options.restrictPublicBuckets; } } @@ -2188,6 +2190,10 @@ export class Bucket extends BucketBase { // Enhanced CDK Analytics Telemetry addConstructMetadata(this, props); + // Set the S3_BUCKET_DEFAULT_BLOCK_PUBLIC_ACCESS_PROPERTIES_TO_TRUE feature flag + s3BucketDefaultBlockPublicAccessPropertiesToTrueFeatureFlag = FeatureFlags.of(this) + .isEnabled(cxapi.S3_BUCKET_DEFAULT_BLOCK_PUBLIC_ACCESS_PROPERTIES_TO_TRUE) ?? false; + this.notificationsHandlerRole = props.notificationsHandlerRole; this.notificationsSkipDestinationValidation = props.notificationsSkipDestinationValidation; diff --git a/packages/aws-cdk-lib/aws-s3/test/bucket.test.ts b/packages/aws-cdk-lib/aws-s3/test/bucket.test.ts index 352ba91750042..853fa2920c476 100644 --- a/packages/aws-cdk-lib/aws-s3/test/bucket.test.ts +++ b/packages/aws-cdk-lib/aws-s3/test/bucket.test.ts @@ -970,6 +970,34 @@ describe('bucket', () => { }); }); + test('unspecified blockPublicAccess properties should default to true', () => { + const stack = new cdk.Stack(); + new s3.Bucket(stack, 'MyBucket', { + blockPublicAccess: new s3.BlockPublicAccess({ + blockPublicPolicy: false, + restrictPublicBuckets: false, + }), + }); + + Template.fromStack(stack).templateMatches({ + 'Resources': { + 'MyBucketF68F3FF0': { + 'Type': 'AWS::S3::Bucket', + 'Properties': { + 'PublicAccessBlockConfiguration': { + 'BlockPublicAcls': true, + 'BlockPublicPolicy': false, + 'IgnorePublicAcls': true, + 'RestrictPublicBuckets': false, + }, + }, + 'DeletionPolicy': 'Retain', + 'UpdateReplacePolicy': 'Retain', + }, + }, + }); + }); + test('bucket with default block public access setting to throw error msg', () => { const stack = new cdk.Stack(); diff --git a/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md b/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md index 102c858104884..23753bbdbc26a 100644 --- a/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md +++ b/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md @@ -90,6 +90,7 @@ Flags come in three types: | [@aws-cdk/aws-iam:oidcRejectUnauthorizedConnections](#aws-cdkaws-iamoidcrejectunauthorizedconnections) | When enabled, the default behaviour of OIDC provider will reject unauthorized connections | 2.177.0 | (fix) | | [@aws-cdk/core:enableAdditionalMetadataCollection](#aws-cdkcoreenableadditionalmetadatacollection) | When enabled, CDK will expand the scope of usage data collected to better inform CDK development and improve communication for security concerns and emerging issues. | 2.178.0 | (config) | | [@aws-cdk/aws-lambda:createNewPoliciesWithAddToRolePolicy](#aws-cdkaws-lambdacreatenewpolicieswithaddtorolepolicy) | When enabled, Lambda will create new inline policies with AddToRolePolicy instead of adding to the Default Policy Statement | 2.180.0 | (fix) | +| [@aws-cdk/aws-s3:blockPublicAccessPropertiesDefaultToTrue](#aws-cdkaws-s3blockpublicaccesspropertiesdefaulttotrue) | When enabled, the properties of class BlockPublicAccess will default to true | V2NEXT | (fix) | @@ -167,7 +168,8 @@ The following json shows the current recommended set of flags, as `cdk init` wou "@aws-cdk/aws-elasticloadbalancingV2:albDualstackWithoutPublicIpv4SecurityGroupRulesDefault": true, "@aws-cdk/aws-iam:oidcRejectUnauthorizedConnections": true, "@aws-cdk/core:enableAdditionalMetadataCollection": true, - "@aws-cdk/aws-lambda:createNewPoliciesWithAddToRolePolicy": true + "@aws-cdk/aws-lambda:createNewPoliciesWithAddToRolePolicy": true, + "@aws-cdk/aws-s3:blockPublicAccessPropertiesDefaultToTrue": true } } ``` @@ -1703,6 +1705,28 @@ This solves an issue where a circular dependency could occur if adding lambda to | ----- | ----- | ----- | | (not in v1) | | | | 2.180.0 | `false` | `true` | + + +### @aws-cdk/aws-s3:blockPublicAccessPropertiesDefaultToTrue + +*When enabled, the properties of class BlockPublicAccess will default to true* (fix) + +Without this flag, the `blockPublicAccess` property has a counter-intuitive and inconsistent behavior. +When the property value is not specified, then all the 4 member properties (`blockPublicAcls`, +`ignorePublicAcls`, `blockPublicPolicy` and `restrictPublicBuckets`) will default to `true`. However, in +cases where selected properties are explicitly set to `false`, the remaining properties for which no value +was specified will also default to `false`. + +Intuitively, if the property is not set explicitly, it must default to `true`. Enabling this flag will exhibit +this behavior. + + +| Since | Default | Recommended | +| ----- | ----- | ----- | +| (not in v1) | | | +| V2NEXT | `false` | `true` | + +**Compatibility with old behavior:** Disable the feature flag to avoid accidental changes to bucket visibility settings. diff --git a/packages/aws-cdk-lib/cx-api/README.md b/packages/aws-cdk-lib/cx-api/README.md index 4002764b11810..a72291583044d 100644 --- a/packages/aws-cdk-lib/cx-api/README.md +++ b/packages/aws-cdk-lib/cx-api/README.md @@ -627,4 +627,25 @@ _cdk.json_ "@aws-cdk/aws-lambda:createNewPoliciesWithAddToRolePolicy": true } } -``` \ No newline at end of file +``` + +* `@aws-cdk/aws-s3:blockPublicAccessPropertiesDefaultToTrue` + +Without this flag, the `blockPublicAccess` property has a counter-intuitive and inconsistent behavior. +When the property value is not specified, then all the 4 member properties (`blockPublicAcls`, +`ignorePublicAcls`, `blockPublicPolicy` and `restrictPublicBuckets`) will default to `true`. However, in +cases where selected properties are explicitly set to `false`, the remaining properties for which no value +was specified will also default to `false`. + +Intuitively, if the property is not set explicitly, it must default to `true`. Enabling this flag will exhibit +this behavior. + +_cdk.json_ + +```json +{ + "context": { + "@aws-cdk/aws-s3:blockPublicAccessPropertiesDefaultToTrue": true + } +} +``` diff --git a/packages/aws-cdk-lib/cx-api/lib/features.ts b/packages/aws-cdk-lib/cx-api/lib/features.ts index 3321fa903bf10..229028a34934c 100644 --- a/packages/aws-cdk-lib/cx-api/lib/features.ts +++ b/packages/aws-cdk-lib/cx-api/lib/features.ts @@ -124,6 +124,7 @@ export const ALB_DUALSTACK_WITHOUT_PUBLIC_IPV4_SECURITY_GROUP_RULES_DEFAULT = '@ export const IAM_OIDC_REJECT_UNAUTHORIZED_CONNECTIONS = '@aws-cdk/aws-iam:oidcRejectUnauthorizedConnections'; export const ENABLE_ADDITIONAL_METADATA_COLLECTION = '@aws-cdk/core:enableAdditionalMetadataCollection'; export const LAMBDA_CREATE_NEW_POLICIES_WITH_ADDTOROLEPOLICY = '@aws-cdk/aws-lambda:createNewPoliciesWithAddToRolePolicy'; +export const S3_BUCKET_DEFAULT_BLOCK_PUBLIC_ACCESS_PROPERTIES_TO_TRUE = '@aws-cdk/aws-s3:blockPublicAccessPropertiesDefaultToTrue'; export const FLAGS: Record = { ////////////////////////////////////////////////////////////////////// @@ -1400,6 +1401,24 @@ export const FLAGS: Record = { introducedIn: { v2: '2.180.0' }, recommendedValue: true, }, + + ////////////////////////////////////////////////////////////////////// + [S3_BUCKET_DEFAULT_BLOCK_PUBLIC_ACCESS_PROPERTIES_TO_TRUE]: { + type: FlagType.BugFix, + summary: 'When enabled, the properties of class BlockPublicAccess will default to true', + detailsMd: ` + Without this flag, the \`blockPublicAccess\` property has a counter-intuitive and inconsistent behavior. + When the property value is not specified, then all the 4 member properties (\`blockPublicAcls\`, + \`ignorePublicAcls\`, \`blockPublicPolicy\` and \`restrictPublicBuckets\`) will default to \`true\`. However, in + cases where selected properties are explicitly set to \`false\`, the remaining properties for which no value + was specified will also default to \`false\`. + + Intuitively, if the property is not set explicitly, it must default to \`true\`. Enabling this flag will exhibit + this behavior.`, + introducedIn: { v2: 'V2NEXT' }, + recommendedValue: true, + compatibilityWithOldBehaviorMd: 'Disable the feature flag to avoid accidental changes to bucket visibility settings.', + }, }; const CURRENT_MV = 'v2'; diff --git a/packages/aws-cdk-lib/recommended-feature-flags.json b/packages/aws-cdk-lib/recommended-feature-flags.json index 5008c39cb1146..20f0da5bb22ff 100644 --- a/packages/aws-cdk-lib/recommended-feature-flags.json +++ b/packages/aws-cdk-lib/recommended-feature-flags.json @@ -65,5 +65,6 @@ "@aws-cdk/aws-elasticloadbalancingV2:albDualstackWithoutPublicIpv4SecurityGroupRulesDefault": true, "@aws-cdk/aws-iam:oidcRejectUnauthorizedConnections": true, "@aws-cdk/core:enableAdditionalMetadataCollection": true, - "@aws-cdk/aws-lambda:createNewPoliciesWithAddToRolePolicy": true + "@aws-cdk/aws-lambda:createNewPoliciesWithAddToRolePolicy": true, + "@aws-cdk/aws-s3:blockPublicAccessPropertiesDefaultToTrue": true } \ No newline at end of file