Skip to content

Conversation

@maczac150
Copy link

Issue # (if applicable)

Closes #35628

Reason for this change

When using EventBridge rules to send events to SQS queues encrypted with imported KMS keys, CDK cannot automatically configure the required KMS key policy permissions. This is because imported keys (via Key.fromKeyArn() or Key.fromLookup()) have an undefined policy that CDK cannot modify.

Without proper KMS permissions, EventBridge fails to send messages to the encrypted queue at runtime, but CDK provides no indication of this misconfiguration during synthesis or deployment.

Root Cause Analysis

When queue.grantSendMessages() is called with a ServicePrincipal (EventBridge), CDK's grant mechanism attempts to add permissions in two ways:

  • Principal Policy: ServicePrincipal is a non-identity principal and does not have its own policy document. The addToPrincipalPolicy() method in principals.ts always returns {statementAdded: false} for non-identity principals.

  • Resource Policy: For imported keys (fromKeyArn() or fromLookup()), the policy property is undefined. When addToResourcePolicy() is called in key.ts, it returns {statementAdded: false} because there is no policy to modify.

This dual failure occurs regardless of whether the KMS key and EventBridge are in the same account or different accounts, because:

  • Same account: Grant.addToPrincipalOrResource() tries principal first, then resource policy

  • Cross-account: Grant.addToPrincipalAndResource() tries both principal and resource policies

In both code paths no statements are added, which leaves the stack misconfigured without any indication at synthesis or deployment time.

Detection Logic

The fix uses Resource.isOwnedResource() to distinguish between CDK-managed and imported keys:

Key Type isOwnedResource Behavior
new Key(...) true No warning
Key.fromCfnKey(cfnKey) true No warning
Key.fromKeyArn(...) false Emits warning
Key.fromLookup(...) false Emits warning

Description of changes

  • Added validateKmsKeyPermissions() method in SqsQueue target to detect imported KMS keys using Resource.isOwnedResource()

  • Emit a warning when an imported KMS key is detected, instructing users to manually add required permissions (kms:Decrypt and kms:GenerateDataKey) to the key policy

  • Added comprehensive documentation in README with usage examples and manual configuration instructions

Describe any new or updated permissions being added

None.
This change only adds a synthesis-time warning and does not modify any IAM permissions. The warning reminds users to manually configure KMS key policy permissions (kms:Decrypt, kms:GenerateDataKey) for imported keys, which CDK cannot modify automatically.

Description of how you validated changes

  • Unit tests: Added new tests in sqs.test.ts to verify that a warning is emitted only for imported KMS keys and not for CDK-managed or unencrypted queues.
  • Integration test: Created integ.sqs-imported-key.ts to demonstrate the warning scenario with an imported KMS key, verifying that the message includes the key ID and required permissions (kms:Decrypt, kms:GenerateDataKey).

Checklist


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

@github-actions github-actions bot added effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. p2 beginning-contributor [Pilot] contributed between 0-2 PRs to the CDK labels Nov 7, 2025
@aws-cdk-automation aws-cdk-automation requested a review from a team November 7, 2025 11:51
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 effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. p2

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sqs/events: Using an SQS queue as the target of an EB Rule leads to an incomplete KMS Key policy if the queue is encrypted with an imported key

1 participant