Closed garysassano closed 1 month ago
Hi @garysassano , thanks for reaching out. I am able to reproduce the scenario with given bucket policy. Its observed that adding a new bucket policy with existing Bucket Policy with autoDeleteObject:true actually leads to error when deleting the stack.
Received response status [FAILED] from custom resource. Message returned: AccessDenied: User: arn:aws:sts::1234567890:assumed-role/BucketAutoDeleteObjectP
ol-CustomS3AutoDeleteObjects-mHw0z310uANA/BucketAutoDeleteObjectPol-CustomS3AutoDeleteObject-mSxwX4IBLB2P is not authorized to perform: s3:GetBucketTagging
on resource: "arn:aws:s3:::my-bucket-c8939193" because no identity-based policy allows the s3:GetBucketTagging action
Sharing my observation -
When a bucket is created with autoDeleteObject:true
-
these are the permissions granted -
this.addToResourcePolicy(new iam.PolicyStatement({
actions: [
// prevent further PutObject calls
...perms.BUCKET_PUT_POLICY_ACTIONS,
// list objects
...perms.BUCKET_READ_METADATA_ACTIONS,
...perms.BUCKET_DELETE_ACTIONS, // and then delete them
],
which results in this snippet of synthesized template when deployed
{
"Action": [
"s3:DeleteObject*",
"s3:GetBucket*",
"s3:List*",
"s3:PutBucketPolicy"
],
but after defining the new policy, one sees the updation in Bucket policy-
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
Hence leading to error during deletion.
@garysassano , it says in the BucketPolicy doc that it should not be preferred way of adding policy -
The bucket policy for an Amazon S3 bucket.
Policies define the operations that are allowed on this resource.
You almost never need to define this construct directly.
All AWS resources that support resource policies have a method called addToResourcePolicy(), which will automatically create a new resource policy if one doesn't exist yet, otherwise it will add to the existing policy.
Prefer to use addToResourcePolicy() instead.
The BucketPolicy is not aware if there is another BucketPolicy being created for the same bucket hence it's not preferred.
The general recommended practice is always use bucket.addToResourcePolicy()
instead.
@garysassano , I just rewrote the code with using addToResourcePolicy()
and what it does it appends the Bucket policy and hence when the stack is destroyed, it succeeds without any error. Please see the shared snippet and template -
const myBucket015 = new s3.Bucket(this, "MyBucket015", {
bucketName: `my-bucket-015`,
enforceSSL: true,
removalPolicy: RemovalPolicy.DESTROY,
autoDeleteObjects: true,
});
myBucket015.addToResourcePolicy( new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
principals: [new iam.ArnPrincipal("3********6")],
actions: ["s3:GetObject", "s3:ListBucket"],
resources: [myBucket015.bucketArn, `${myBucket015.bucketArn}/*`],
}));
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-bucket-015",
"arn:aws:s3:::my-bucket-015/*"
],
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
}
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::3*******6:role/BucketV2IssueStack-CustomS3AutoDeleteObjectsCustomR-op0fiXi89QWA"
},
"Action": [
"s3:DeleteObject*",
"s3:GetBucket*",
"s3:List*",
"s3:PutBucketPolicy"
],
"Resource": [
"arn:aws:s3:::my-bucket-015",
"arn:aws:s3:::my-bucket-015/*"
]
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::3*******6:root"
},
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-bucket-015",
"arn:aws:s3:::my-bucket-015/*"
]
}
]
}
Hope that would be helpful.
Comments on closed issues and PRs are hard for our team to see. If you need help, please open a new issue that references this one.
Describe the bug
We are going to deploy this CDK stack and observe the behavior.
Regression Issue
Last Known Working CDK Version
No response
Expected Behavior
I expected the
cdk deploy
to fail immediately due to a conflict between theautoDeleteObjects
custom resource and theBucketPolicy
we defined. Since only one bucket policy can exist at a time, the system should have detected this conflict and prevented the deployment.Current Behavior
However, the stack deploys successfully without any error.
Inspecting the S3 bucket policy shows that the
BucketPolicy
we explicitly created overrides the one generated byautoDeleteObjects
:When attempting to destroy the stack with
cdk destroy
, it fails because the Lambda function linked toautoDeleteObjects
custom resource lacks the necessary permissions to delete the S3 bucket. This occurs because theBucketPolicy
we defined overrides the policy that grants the required permissions.Reproduction Steps
see above
Possible Solution
The CDK should enforce a check to prevent defining a
BucketPolicy
that overrides the permissions needed by theautoDeleteObjects
custom resource. Although the deployment works, it leads to conflicts during stack destruction due to missing permissions.Additional Information/Context
No response
CDK CLI Version
2.156.0
Framework Version
No response
Node.js Version
20.17.0
OS
Ubuntu 22.04.3 LTS
Language
TypeScript
Language Version
No response
Other information
No response