Skip to content

fix(custom-resource-handler): remove hardcoded partition in s3 auto-delete-objects handler - #37963

Open
Khangdang1690 wants to merge 2 commits into
aws:mainfrom
Khangdang1690:fix/33212-s3-auto-delete-partition
Open

fix(custom-resource-handler): remove hardcoded partition in s3 auto-delete-objects handler#37963
Khangdang1690 wants to merge 2 commits into
aws:mainfrom
Khangdang1690:fix/33212-s3-auto-delete-partition

Conversation

@Khangdang1690

Copy link
Copy Markdown

Issue # (if applicable)

Closes #33212.

Reason for this change

The auto-delete-objects custom resource Lambda hardcodes arn:aws:s3:::${bucketName}/* when attaching the pre-delete s3:PutObject deny policy. The literal aws partition silently breaks the deny policy in aws-cn (China) and aws-us-gov (GovCloud), where bucket ARNs are arn:aws-cn:... / arn:aws-us-gov:.... The s3:PutObject deny statement is non-fatal (the bucket still gets emptied), so the issue is silent — the race-condition protection against external writers is simply absent in non-default partitions.

The CDK team filed this themselves when the @cdklabs/no-literal-partition lint rule flagged the line; an inline eslint-disable was added with a TODO at the time.

Description of changes

The handler now derives the partition at runtime from event.ServiceToken, which CloudFormation always populates with the Lambda's own ARN. Since the Lambda is always provisioned in the same partition as the bucket it manages, this is the correct partition to use in the deny ARN. The eslint suppression and TODO are removed.

async function denyWrites(bucketName: string, serviceToken: string) {
  // ServiceToken is this Lambda's ARN — same partition as the bucket.
  const partition = serviceToken.split(':')[1];
  // ...
  Resource: [`arn:${partition}:s3:::${bucketName}/*`],
}

Alternative considered and rejected: passing the partition to the handler as a Lambda environment variable populated from Stack.of(scope).partition at synth time. That works but adds a new Environment.Variables entry to the provider Lambda in every stack with autoDeleteObjects: true, which would regenerate ~100 integration test snapshots across the framework-integ package. The event.ServiceToken approach delivers the same correctness with zero synthesized-template changes.

Describe any new or updated permissions being added

None.

Description of how you validated changes

  • Updated existing unit tests for Delete events to provide a top-level ServiceToken ARN (the canonical CloudFormation custom-resource field) so they continue to assert on the existing arn:aws:s3:::MyBucket/* deny ARN.
  • Added a new unit test 'deny policy ARN uses the partition from the ServiceToken (aws-cn)' that fires a Delete event with an arn:aws-cn:... ServiceToken and asserts the resulting deny statement uses arn:aws-cn:s3:::MyBucket/*.
  • All 16 tests pass (15 existing + 1 new) via yarn test in packages/@aws-cdk/custom-resource-handlers.
  • No integration test snapshots are affected by this change (no construct-side modifications, no env var added to the Lambda).

Checklist


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

…elete-objects handler

Derive partition from event.ServiceToken at runtime instead of hardcoding 'aws'.
CloudFormation always sets ServiceToken to this Lambda's own ARN, which is in
the same partition as the bucket being managed. Fixes silent failure of the
pre-delete s3:PutObject deny policy in aws-cn and aws-us-gov partitions.

fixes aws#33212
@github-actions github-actions Bot added beginning-contributor [Pilot] contributed between 0-2 PRs to the CDK bug This issue is a bug. p2 labels May 21, 2026

@aws-cdk-automation aws-cdk-automation left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pull request linter fails with the following errors:

❌ Fixes must contain a change to an integration test file and the resulting snapshot.

If you believe this pull request should receive an exemption, please comment and provide a justification. A comment requesting an exemption should contain the text Exemption Request. Additionally, if clarification is needed, add Clarification Request to a comment.

✅ A exemption request has been requested. Please wait for a maintainer's review.

@Khangdang1690

Copy link
Copy Markdown
Author

Exemption Request

This is a runtime-only fix in @aws-cdk/custom-resource-handlers/lib/aws-s3/auto-delete-objects-handler/index.ts. There are no construct-side changes, so the synthesized CloudFormation template is unchanged in the aws (commercial) partition.

The bug only manifests in aws-cn (China) and aws-us-gov (GovCloud), where bucket ARNs use arn:aws-cn:... / arn:aws-us-gov:.... CDK integ tests run only in the commercial partition, where Stack.of(scope).partition === 'aws' — the deny policy ARN before this fix (arn:aws:s3:::${bucketName}/*) and after this fix (arn:${partition}:s3:::${bucketName}/* with partition === 'aws') are byte-identical. An integ test in aws cannot distinguish broken from fixed behavior.

The fix is covered by a new unit test in auto-delete-objects-handler.test.ts ('deny policy ARN uses the partition from the ServiceToken (aws-cn)'), which fires a synthetic Delete event with a ServiceToken in the aws-cn partition and asserts the resulting deny policy is arn:aws-cn:s3:::MyBucket/*. This is the only level at which the fix is observable.

If a reviewer can suggest a way to exercise non-aws partition behavior in the existing integ test infrastructure, happy to add one. Otherwise the unit test is the strongest available verification.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

beginning-contributor [Pilot] contributed between 0-2 PRs to the CDK bug This issue is a bug. p2 pr-linter/exemption-requested The contributor has requested an exemption to the PR Linter feedback.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

(custom-resource-handler): hardcoded partition in s3 auto-delete-objects-handler

3 participants