Skip to content

Commit f1c0926

Browse files
fix(sns): for SSE topics, add KMS permissions in grantPublish (#32794)
### Issue # (if applicable) Fixes #18387, #31012, #24848 Pre-requisite for #16271, #29511 ### Reason for this change For SNS topics with SSE enabled, the grants added by `grantPublish` are insufficient, since they don't include any KMS actions. The SNS docs discuss what's required to publish to an encrypted topic [here](https://docs.aws.amazon.com/sns/latest/dg/sns-key-management.html#sns-what-permissions-for-sse) (`sns:Publish`, `kms:Decrypt`, `kms:GenerateKeyData*`). ### Description of changes I used the SQS queue implementation as a reference, since it's configured similarly, etc. * Have `Topic#grantPublish` grant `kms:Decrypt` + `kms:GenerateKeyData*` * This is least-privilege, but slightly inconsistent with SQS queues, which [need these same actions](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-key-management.html) and use `grantEncryptDecrypt` (but I have no preference -- just let me know what's best) * Exposes `masterKey` as a property of `ITopic` so callers can access it after creation * Enables [this](#16271 (comment)), for example, and in general makes it consistent with SQS queues ### Describe any new or updated permissions being added (Discussed above) ### Description of how you validated changes * Unit/integration tests * `yarn integ test/aws-sns/test/integ.sns.js --update-on-failed` ### Checklist - [X] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent b3edd0d commit f1c0926

File tree

15 files changed

+36317
-50
lines changed

15 files changed

+36317
-50
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import os
2+
import boto3
3+
4+
client = boto3.client('sns')
5+
6+
def lambda_handler(event, context):
7+
client.publish(TopicArn=os.environ['TOPIC_ARN'], Message='hello world')
8+
return 'published successfully'

packages/@aws-cdk-testing/framework-integ/test/aws-sns/test/integ.sns.js.snapshot/SNSInteg.assets.json

+16-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-sns/test/integ.sns.js.snapshot/SNSInteg.template.json

+140-7
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,6 @@
132132
"Type": "AWS::SNS::Topic",
133133
"Properties": {
134134
"DisplayName": "fooDisplayName2",
135-
"KmsMasterKeyId": {
136-
"Fn::GetAtt": [
137-
"CustomKey1E6D0D07",
138-
"Arn"
139-
]
140-
},
141135
"TopicName": "fooTopic2"
142136
}
143137
},
@@ -166,8 +160,26 @@
166160
{
167161
"Action": "sns:Publish",
168162
"Effect": "Allow",
163+
"Resource": [
164+
{
165+
"Ref": "MyTopic288CE2107"
166+
},
167+
{
168+
"Ref": "MyTopic3134CFDFB"
169+
}
170+
]
171+
},
172+
{
173+
"Action": [
174+
"kms:Decrypt",
175+
"kms:GenerateDataKey*"
176+
],
177+
"Effect": "Allow",
169178
"Resource": {
170-
"Ref": "MyTopic288CE2107"
179+
"Fn::GetAtt": [
180+
"CustomKey1E6D0D07",
181+
"Arn"
182+
]
171183
}
172184
}
173185
],
@@ -180,6 +192,127 @@
180192
}
181193
]
182194
}
195+
},
196+
"MyTopic3134CFDFB": {
197+
"Type": "AWS::SNS::Topic",
198+
"Properties": {
199+
"DisplayName": "fooDisplayName3",
200+
"KmsMasterKeyId": {
201+
"Fn::GetAtt": [
202+
"CustomKey1E6D0D07",
203+
"Arn"
204+
]
205+
},
206+
"TopicName": "fooTopic3"
207+
}
208+
},
209+
"PublishEncryptedTopicServiceRole267CEDDE": {
210+
"Type": "AWS::IAM::Role",
211+
"Properties": {
212+
"AssumeRolePolicyDocument": {
213+
"Statement": [
214+
{
215+
"Action": "sts:AssumeRole",
216+
"Effect": "Allow",
217+
"Principal": {
218+
"Service": "lambda.amazonaws.com"
219+
}
220+
}
221+
],
222+
"Version": "2012-10-17"
223+
},
224+
"ManagedPolicyArns": [
225+
{
226+
"Fn::Join": [
227+
"",
228+
[
229+
"arn:",
230+
{
231+
"Ref": "AWS::Partition"
232+
},
233+
":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
234+
]
235+
]
236+
}
237+
]
238+
}
239+
},
240+
"PublishEncryptedTopicServiceRoleDefaultPolicy85E257A5": {
241+
"Type": "AWS::IAM::Policy",
242+
"Properties": {
243+
"PolicyDocument": {
244+
"Statement": [
245+
{
246+
"Action": "sns:Publish",
247+
"Effect": "Allow",
248+
"Resource": {
249+
"Ref": "MyTopic3134CFDFB"
250+
}
251+
},
252+
{
253+
"Action": [
254+
"kms:Decrypt",
255+
"kms:GenerateDataKey*"
256+
],
257+
"Effect": "Allow",
258+
"Resource": {
259+
"Fn::GetAtt": [
260+
"CustomKey1E6D0D07",
261+
"Arn"
262+
]
263+
}
264+
}
265+
],
266+
"Version": "2012-10-17"
267+
},
268+
"PolicyName": "PublishEncryptedTopicServiceRoleDefaultPolicy85E257A5",
269+
"Roles": [
270+
{
271+
"Ref": "PublishEncryptedTopicServiceRole267CEDDE"
272+
}
273+
]
274+
}
275+
},
276+
"PublishEncryptedTopic5F9F9437": {
277+
"Type": "AWS::Lambda::Function",
278+
"Properties": {
279+
"Code": {
280+
"S3Bucket": {
281+
"Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
282+
},
283+
"S3Key": "801b9d403e9ac842f362e817998346ed7c0bfe96c7b4d405a20de49a2abeef90.zip"
284+
},
285+
"Environment": {
286+
"Variables": {
287+
"TOPIC_ARN": {
288+
"Ref": "MyTopic3134CFDFB"
289+
}
290+
}
291+
},
292+
"FunctionName": "publish-encrypted-topic",
293+
"Handler": "index.lambda_handler",
294+
"Role": {
295+
"Fn::GetAtt": [
296+
"PublishEncryptedTopicServiceRole267CEDDE",
297+
"Arn"
298+
]
299+
},
300+
"Runtime": "python3.12"
301+
},
302+
"DependsOn": [
303+
"PublishEncryptedTopicServiceRoleDefaultPolicy85E257A5",
304+
"PublishEncryptedTopicServiceRole267CEDDE"
305+
]
306+
}
307+
},
308+
"Outputs": {
309+
"ExportsOutputRefPublishEncryptedTopic5F9F9437B383DB14": {
310+
"Value": {
311+
"Ref": "PublishEncryptedTopic5F9F9437"
312+
},
313+
"Export": {
314+
"Name": "SNSInteg:ExportsOutputRefPublishEncryptedTopic5F9F9437B383DB14"
315+
}
183316
}
184317
},
185318
"Parameters": {

packages/@aws-cdk-testing/framework-integ/test/aws-sns/test/integ.sns.js.snapshot/SNSTestDefaultTestDeployAssert607DA316.assets.json

+32
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)