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): clarifying blockPublicAccess behavior with v2 #33668

Closed
wants to merge 6 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat: temp add
  • Loading branch information
Ike Nefcy committed Mar 1, 2025
commit e6a97546bca7dedcd8d22e5277bd2fcb1f4160bf
74 changes: 71 additions & 3 deletions packages/aws-cdk-lib/aws-s3/lib/bucket.ts
Original file line number Diff line number Diff line change
@@ -1075,6 +1075,10 @@ export interface BlockPublicAccessOptions {
readonly restrictPublicBuckets?: boolean;
}

/**
*
* @depreacted Use `BlockPublicAccessV2` instead.
*/
export class BlockPublicAccess {
public static readonly BLOCK_ALL = new BlockPublicAccess({
blockPublicAcls: true,
@@ -1101,6 +1105,33 @@ export class BlockPublicAccess {
}
}

/**
*
* This class is used to create shortcut options for blockPublicAccessV2
*/
export class BlockPublicAccessV2 {
/**
* Use this option if you want to ensure every public access method is blocked.
* However keep in mind that this is the default state of an S3 bucket, and leaving blockPublicAccessV2 undefined would also work.
*/
public static readonly BLOCK_ALL: BlockPublicAccessOptions = {
blockPublicAcls: true,
blockPublicPolicy: true,
ignorePublicAcls: true,
restrictPublicBuckets: true,
};

/**
* Use this option if you want to only block the ACLs, using this will set blockPublicPolicy and restrictPublicBuckets to false.
*/
public static readonly BLOCK_ACLS_ONLY: BlockPublicAccessOptions = {
blockPublicAcls: true,
blockPublicPolicy: false,
ignorePublicAcls: true,
restrictPublicBuckets: false,
};
}

/**
* Specifies a metrics configuration for the CloudWatch request metrics from an Amazon S3 bucket.
*/
@@ -1820,11 +1851,23 @@ export interface BucketProps {
*
* @see https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html
*
*
* @default - CloudFormation defaults will apply. New buckets and objects don't allow public access, but users can modify bucket policies or object permissions to allow public access
*
* @deprecated Use `blockPublicAccessV2` instead.
*
*/
readonly blockPublicAccess?: BlockPublicAccess;

/**
* The block public access configuration of this bucket.
*
* @see https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html
*
*
* @default - CloudFormation defaults will apply. New buckets and objects don't allow public access, but users can modify bucket policies or object permissions to allow public access
*/
readonly blockPublicAccessV2?: BlockPublicAccessOptions;

/**
* The metrics configuration of this bucket.
*
@@ -1956,7 +1999,7 @@ export interface Tag {
* import { RemovalPolicy } from 'aws-cdk-lib';
*
* new s3.Bucket(scope, 'Bucket', {
* blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
* blockPublicAccessV2: s3.BlockPublicAccessV2.BLOCK_ALL,
* encryption: s3.BucketEncryption.S3_MANAGED,
* enforceSSL: true,
* versioned: true,
@@ -2196,6 +2239,17 @@ export class Bucket extends BucketBase {

Bucket.validateBucketName(this.physicalName);

if (props.blockPublicAccess && props.blockPublicAccessV2) {
throw new ValidationError('you cannot use properties blockPublicAccess and blockPublicAccessV2 together. blockPublicAccess is deprecated, consider leaving this property undefined.', this);
}

let blockPublicAccess: BlockPublicAccessOptions | undefined = props.blockPublicAccessV2;
if (props.blockPublicAccessV2) {
blockPublicAccess = this.setBlockPublicAccessDefaults(props.blockPublicAccessV2);
}

const blockPublicAccessMethod = blockPublicAccess ?? props.blockPublicAccess;

const websiteConfiguration = this.renderWebsiteConfiguration(props);
this.isWebsite = (websiteConfiguration !== undefined);

@@ -2210,7 +2264,7 @@ export class Bucket extends BucketBase {
versioningConfiguration: props.versioned ? { status: 'Enabled' } : undefined,
lifecycleConfiguration: Lazy.any({ produce: () => this.parseLifecycleConfiguration() }),
websiteConfiguration,
publicAccessBlockConfiguration: props.blockPublicAccess,
publicAccessBlockConfiguration: blockPublicAccessMethod,
metricsConfigurations: Lazy.any({ produce: () => this.parseMetricConfiguration() }),
corsConfiguration: Lazy.any({ produce: () => this.parseCorsConfiguration() }),
accessControl: Lazy.string({ produce: () => this.accessControl }),
@@ -3026,6 +3080,20 @@ export class Bucket extends BucketBase {
// the bucket as a side effect.
Tags.of(this._resource).add(AUTO_DELETE_OBJECTS_TAG, 'true');
}

/**
* 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,
};
}
}

/**
27 changes: 26 additions & 1 deletion packages/aws-cdk-lib/aws-s3/test/bucket.test.ts
Original file line number Diff line number Diff line change
@@ -948,7 +948,7 @@ describe('bucket', () => {
});
});

test('bucket with custom block public access setting', () => {
test('bucket with custom block public access setting - blockPublicAccess deprecated', () => {
const stack = new cdk.Stack();
new s3.Bucket(stack, 'MyBucket', {
blockPublicAccess: new s3.BlockPublicAccess({ restrictPublicBuckets: true }),
@@ -970,6 +970,31 @@ describe('bucket', () => {
});
});

test('bucket with custom block public access setting - blockPublicAccessV2', () => {
const stack = new cdk.Stack();
new s3.Bucket(stack, 'MyBucket', {
blockPublicAccessV2: { 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',
},
},
});
});

test('bucket with default block public access setting to throw error msg', () => {
const stack = new cdk.Stack();