From bf3101307468ce5a83e93b9cb151585fde3b2056 Mon Sep 17 00:00:00 2001 From: Sebastien Corbiere Date: Mon, 10 Mar 2025 14:23:28 -0700 Subject: [PATCH 1/2] test(events): add failing test for EventBus.grantPutEventsTo with service principals (issue #22080) --- .../aws-events/test/event-bus.grant.test.ts | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 packages/aws-cdk-lib/aws-events/test/event-bus.grant.test.ts diff --git a/packages/aws-cdk-lib/aws-events/test/event-bus.grant.test.ts b/packages/aws-cdk-lib/aws-events/test/event-bus.grant.test.ts new file mode 100644 index 0000000000000..9cfdda4a3071e --- /dev/null +++ b/packages/aws-cdk-lib/aws-events/test/event-bus.grant.test.ts @@ -0,0 +1,50 @@ +import { Template } from '../../assertions'; +import * as iam from '../../aws-iam'; +import { Stack } from '../../core'; +import { EventBus } from '../lib'; + +describe('EventBus grants', () => { + test('grantPutEventsTo creates EventBusPolicy for service principal', () => { + // GIVEN + const stack = new Stack(); + const eventBus = new EventBus(stack, 'EventBus'); + const servicePrincipal = new iam.ServicePrincipal('states.amazonaws.com'); + + // WHEN + eventBus.grantPutEventsTo(servicePrincipal); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Events::EventBusPolicy', { + Action: 'events:PutEvents', + Principal: { Service: 'states.amazonaws.com' }, + StatementId: expect.any(String), + EventBusName: { Ref: expect.any(String) }, + }); + }); + + test('grantPutEventsTo creates IAM policy for IAM principal', () => { + // GIVEN + const stack = new Stack(); + const eventBus = new EventBus(stack, 'EventBus'); + const role = new iam.Role(stack, 'Role', { + assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), + }); + + // WHEN + eventBus.grantPutEventsTo(role); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [{ + Action: 'events:PutEvents', + Effect: 'Allow', + Resource: { + 'Fn::GetAtt': [expect.any(String), 'Arn'], + }, + }], + Version: '2012-10-17', + }, + }); + }); +}); From 50bd7920a4538275cb5255fd2fdbab3f90edd146 Mon Sep 17 00:00:00 2001 From: Sebastien Corbiere Date: Mon, 10 Mar 2025 15:47:58 -0700 Subject: [PATCH 2/2] fix(events): EventBus.grantPutEventsTo now correctly handles service principals (fixes #22080) --- .../cdk-integ-assets-bundling.assets.json | 2 +- .../cdk.out | 2 +- .../integ.json | 2 +- .../manifest.json | 54 ++++++++++++++++++- .../tree.json | 38 +++++++++++-- ...efaultTestDeployAssertE3E7D2A4.assets.json | 2 +- .../cdk-integ-assets-bundling.assets.json | 2 +- .../cdk.out | 2 +- .../integ.json | 2 +- .../manifest.json | 54 ++++++++++++++++++- .../tree.json | 41 ++++++++++++-- .../aws-cdk-lib/aws-events/lib/event-bus.ts | 15 ++++++ .../aws-events/test/event-bus.grant.test.ts | 8 +-- 13 files changed, 204 insertions(+), 20 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.bundling.lit.js.snapshot/cdk-integ-assets-bundling.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.bundling.lit.js.snapshot/cdk-integ-assets-bundling.assets.json index d6d26275d807c..569f2538f8a72 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.bundling.lit.js.snapshot/cdk-integ-assets-bundling.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.bundling.lit.js.snapshot/cdk-integ-assets-bundling.assets.json @@ -1,5 +1,5 @@ { - "version": "38.0.1", + "version": "40.0.0", "files": { "96eb17ab9d98dd42b972aa0dd468f59024f21aba33c7d792b8ebe7a8d378e2b6": { "source": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.bundling.lit.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.bundling.lit.js.snapshot/cdk.out index c6e612584e352..1e02a2deb191b 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.bundling.lit.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.bundling.lit.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"38.0.1"} \ No newline at end of file +{"version":"40.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.bundling.lit.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.bundling.lit.js.snapshot/integ.json index 9b0515346264f..11a7aec04cb43 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.bundling.lit.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.bundling.lit.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "38.0.1", + "version": "40.0.0", "testCases": { "integ.assets.bundling.lit": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.bundling.lit.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.bundling.lit.js.snapshot/manifest.json index 3225dc6e50c89..1199bad6be4e1 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.bundling.lit.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.bundling.lit.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "38.0.1", + "version": "40.0.0", "artifacts": { "cdk-integ-assets-bundling.assets": { "type": "cdk:asset-manifest", @@ -34,12 +34,64 @@ "cdk-integ-assets-bundling.assets" ], "metadata": { + "/cdk-integ-assets-bundling/MyUser": [ + { + "type": "aws:cdk:analytics:construct", + "data": "*" + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "addToPrincipalPolicy": [ + {} + ] + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "attachInlinePolicy": [ + "*" + ] + } + } + ], "/cdk-integ-assets-bundling/MyUser/Resource": [ { "type": "aws:cdk:logicalId", "data": "MyUserDC45028B" } ], + "/cdk-integ-assets-bundling/MyUser/DefaultPolicy": [ + { + "type": "aws:cdk:analytics:construct", + "data": "*" + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "attachToUser": [ + "*" + ] + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "attachToUser": [ + "*" + ] + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "addStatements": [ + {} + ] + } + } + ], "/cdk-integ-assets-bundling/MyUser/DefaultPolicy/Resource": [ { "type": "aws:cdk:logicalId", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.bundling.lit.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.bundling.lit.js.snapshot/tree.json index 7ce2b43b78dec..2d15ea6efe207 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.bundling.lit.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.bundling.lit.js.snapshot/tree.json @@ -25,7 +25,8 @@ "path": "cdk-integ-assets-bundling/BundledAsset/AssetBucket", "constructInfo": { "fqn": "aws-cdk-lib.aws_s3.BucketBase", - "version": "0.0.0" + "version": "0.0.0", + "metadata": [] } } }, @@ -122,13 +123,44 @@ }, "constructInfo": { "fqn": "aws-cdk-lib.aws_iam.Policy", - "version": "0.0.0" + "version": "0.0.0", + "metadata": [ + "*", + { + "attachToUser": [ + "*" + ] + }, + { + "attachToUser": [ + "*" + ] + }, + { + "addStatements": [ + {} + ] + } + ] } } }, "constructInfo": { "fqn": "aws-cdk-lib.aws_iam.User", - "version": "0.0.0" + "version": "0.0.0", + "metadata": [ + "*", + { + "addToPrincipalPolicy": [ + {} + ] + }, + { + "attachInlinePolicy": [ + "*" + ] + } + ] } }, "BootstrapVersion": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.file-bundling.lit.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.file-bundling.lit.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json index 8bbe077289ad2..1cbd2e344eaa5 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.file-bundling.lit.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.file-bundling.lit.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json @@ -1,5 +1,5 @@ { - "version": "38.0.1", + "version": "40.0.0", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.file-bundling.lit.js.snapshot/cdk-integ-assets-bundling.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.file-bundling.lit.js.snapshot/cdk-integ-assets-bundling.assets.json index f030a333d5c34..81efc5f3958e6 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.file-bundling.lit.js.snapshot/cdk-integ-assets-bundling.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.file-bundling.lit.js.snapshot/cdk-integ-assets-bundling.assets.json @@ -1,5 +1,5 @@ { - "version": "38.0.1", + "version": "40.0.0", "files": { "68c2f55451f9566ae0c08664249d08921ab032b2aea797bd8ba293885bf00d64": { "source": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.file-bundling.lit.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.file-bundling.lit.js.snapshot/cdk.out index c6e612584e352..1e02a2deb191b 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.file-bundling.lit.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.file-bundling.lit.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"38.0.1"} \ No newline at end of file +{"version":"40.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.file-bundling.lit.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.file-bundling.lit.js.snapshot/integ.json index fade2f3000619..a0022230708e1 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.file-bundling.lit.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.file-bundling.lit.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "38.0.1", + "version": "40.0.0", "testCases": { "IntegTest/DefaultTest": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.file-bundling.lit.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.file-bundling.lit.js.snapshot/manifest.json index 2f0bf9a596d38..c5d111f79bcb1 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.file-bundling.lit.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.file-bundling.lit.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "38.0.1", + "version": "40.0.0", "artifacts": { "cdk-integ-assets-bundling.assets": { "type": "cdk:asset-manifest", @@ -34,12 +34,64 @@ "cdk-integ-assets-bundling.assets" ], "metadata": { + "/cdk-integ-assets-bundling/MyUser": [ + { + "type": "aws:cdk:analytics:construct", + "data": "*" + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "addToPrincipalPolicy": [ + {} + ] + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "attachInlinePolicy": [ + "*" + ] + } + } + ], "/cdk-integ-assets-bundling/MyUser/Resource": [ { "type": "aws:cdk:logicalId", "data": "MyUserDC45028B" } ], + "/cdk-integ-assets-bundling/MyUser/DefaultPolicy": [ + { + "type": "aws:cdk:analytics:construct", + "data": "*" + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "attachToUser": [ + "*" + ] + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "attachToUser": [ + "*" + ] + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "addStatements": [ + {} + ] + } + } + ], "/cdk-integ-assets-bundling/MyUser/DefaultPolicy/Resource": [ { "type": "aws:cdk:logicalId", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.file-bundling.lit.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.file-bundling.lit.js.snapshot/tree.json index 673dbde10122e..65453b8f17d37 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.file-bundling.lit.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3-assets/test/integ.assets.file-bundling.lit.js.snapshot/tree.json @@ -25,7 +25,8 @@ "path": "cdk-integ-assets-bundling/BundledAsset/AssetBucket", "constructInfo": { "fqn": "aws-cdk-lib.aws_s3.BucketBase", - "version": "0.0.0" + "version": "0.0.0", + "metadata": [] } } }, @@ -122,13 +123,44 @@ }, "constructInfo": { "fqn": "aws-cdk-lib.aws_iam.Policy", - "version": "0.0.0" + "version": "0.0.0", + "metadata": [ + "*", + { + "attachToUser": [ + "*" + ] + }, + { + "attachToUser": [ + "*" + ] + }, + { + "addStatements": [ + {} + ] + } + ] } } }, "constructInfo": { "fqn": "aws-cdk-lib.aws_iam.User", - "version": "0.0.0" + "version": "0.0.0", + "metadata": [ + "*", + { + "addToPrincipalPolicy": [ + {} + ] + }, + { + "attachInlinePolicy": [ + "*" + ] + } + ] } }, "BundledAssetWithoutExtension": { @@ -148,7 +180,8 @@ "path": "cdk-integ-assets-bundling/BundledAssetWithoutExtension/AssetBucket", "constructInfo": { "fqn": "aws-cdk-lib.aws_s3.BucketBase", - "version": "0.0.0" + "version": "0.0.0", + "metadata": [] } } }, diff --git a/packages/aws-cdk-lib/aws-events/lib/event-bus.ts b/packages/aws-cdk-lib/aws-events/lib/event-bus.ts index 05ba131708d8b..4819f6ad678a6 100644 --- a/packages/aws-cdk-lib/aws-events/lib/event-bus.ts +++ b/packages/aws-cdk-lib/aws-events/lib/event-bus.ts @@ -177,6 +177,21 @@ abstract class EventBusBase extends Resource implements IEventBus { } public grantPutEventsTo(grantee: iam.IGrantable): iam.Grant { + // Special handling for service principals + if (grantee.grantPrincipal instanceof iam.ServicePrincipal) { + const policyStatementId = `AllowPutEvents-${this.node.id}`; + + new CfnEventBusPolicy(this, policyStatementId, { + action: 'events:PutEvents', + principal: grantee.grantPrincipal.service, + statementId: policyStatementId, + eventBusName: this.eventBusName, + }); + + return iam.Grant.drop(grantee, 'Service principal permissions handled via EventBusPolicy'); + } + + // Existing implementation for IAM roles/users return iam.Grant.addToPrincipal({ grantee, actions: ['events:PutEvents'], diff --git a/packages/aws-cdk-lib/aws-events/test/event-bus.grant.test.ts b/packages/aws-cdk-lib/aws-events/test/event-bus.grant.test.ts index 9cfdda4a3071e..bae5be5a72b8c 100644 --- a/packages/aws-cdk-lib/aws-events/test/event-bus.grant.test.ts +++ b/packages/aws-cdk-lib/aws-events/test/event-bus.grant.test.ts @@ -16,9 +16,9 @@ describe('EventBus grants', () => { // THEN Template.fromStack(stack).hasResourceProperties('AWS::Events::EventBusPolicy', { Action: 'events:PutEvents', - Principal: { Service: 'states.amazonaws.com' }, - StatementId: expect.any(String), - EventBusName: { Ref: expect.any(String) }, + Principal: 'states.amazonaws.com', + StatementId: 'AllowPutEvents-EventBus', + EventBusName: { Ref: 'EventBus7B8748AA' }, }); }); @@ -40,7 +40,7 @@ describe('EventBus grants', () => { Action: 'events:PutEvents', Effect: 'Allow', Resource: { - 'Fn::GetAtt': [expect.any(String), 'Arn'], + 'Fn::GetAtt': ['EventBus7B8748AA', 'Arn'], }, }], Version: '2012-10-17',