feat(events-targets): warn when using SQS with imported KMS keys #35980
+969
−2
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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()orKey.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()orfromLookup()), the policy property is undefined. WhenaddToResourcePolicy()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 policyCross-account:
Grant.addToPrincipalAndResource()tries both principal and resource policiesIn 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:
new Key(...)Key.fromCfnKey(cfnKey)Key.fromKeyArn(...)Key.fromLookup(...)Description of changes
Added
validateKmsKeyPermissions()method in SqsQueue target to detect imported KMS keys usingResource.isOwnedResource()Emit a warning when an imported KMS key is detected, instructing users to manually add required permissions (
kms:Decryptandkms:GenerateDataKey) to the key policyAdded 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
sqs.test.tsto verify that a warning is emitted only for imported KMS keys and not for CDK-managed or unencrypted queues.integ.sqs-imported-key.tsto 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