Skip to content

Commit 52b7019

Browse files
authored
fix(stepfunctions-tasks): SqsSendMessage is missing KMS permissions (#20990)
The SqsSendMessage task does not add the required KMS permissions when the destination queue uses a custom encryption key. This changes adds the `kms:Decrypt` and `kms:GenerateDataKey*` actions. ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Unconventional Dependencies: * [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies) ### New Features * [x] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [x] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 7f4f150 commit 52b7019

File tree

7 files changed

+737
-0
lines changed

7 files changed

+737
-0
lines changed

packages/@aws-cdk/aws-stepfunctions-tasks/lib/sqs/send-message.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,16 @@ export class SqsSendMessage extends sfn.TaskStateBase {
8484
resources: [this.props.queue.queueArn],
8585
}),
8686
];
87+
88+
// sending to an encrypted queue requires
89+
// permissions on the associated kms key
90+
if (this.props.queue.encryptionMasterKey) {
91+
this.taskPolicies.push(
92+
new iam.PolicyStatement({
93+
actions: ['kms:Decrypt', 'kms:GenerateDataKey*'],
94+
resources: [this.props.queue.encryptionMasterKey.keyArn],
95+
}));
96+
}
8797
}
8898

8999
/**
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import * as sqs from '@aws-cdk/aws-sqs';
2+
import * as sfn from '@aws-cdk/aws-stepfunctions';
3+
import * as cdk from '@aws-cdk/core';
4+
import { SqsSendMessage } from '../../lib/sqs/send-message';
5+
6+
/*
7+
* Creates a state machine with a task state to send a message to an SQS
8+
* queue.
9+
*
10+
* When the state machine is executed, it will send a message to our
11+
* queue, which can subsequently be consumed.
12+
*
13+
* Stack verification steps:
14+
* The generated State Machine can be executed from the CLI (or Step Functions console)
15+
* and runs with an execution status of `Succeeded`.
16+
*
17+
* -- aws stepfunctions start-execution --state-machine-arn <state-machine-arn-from-output> provides execution arn
18+
* -- aws stepfunctions describe-execution --execution-arn <from previous command> returns a status of `Succeeded`
19+
* -- aws sqs receive-message --queue-url <queue-url-from-output> has a message of 'sending message over'
20+
*/
21+
const app = new cdk.App();
22+
const stack = new cdk.Stack(app, 'aws-stepfunctions-tasks-sqs-send-message-integ');
23+
const queue = new sqs.Queue(stack, 'show-me-the-messages', {
24+
encryption: sqs.QueueEncryption.KMS,
25+
});
26+
27+
const sendMessageTask = new SqsSendMessage(stack, 'send message to sqs', {
28+
queue,
29+
messageBody: sfn.TaskInput.fromText('sending message over'),
30+
});
31+
32+
const finalStatus = new sfn.Pass(stack, 'Final step');
33+
34+
const chain = sfn.Chain.start(sendMessageTask)
35+
.next(finalStatus);
36+
37+
const sm = new sfn.StateMachine(stack, 'StateMachine', {
38+
definition: chain,
39+
timeout: cdk.Duration.seconds(30),
40+
});
41+
42+
new cdk.CfnOutput(stack, 'stateMachineArn', {
43+
value: sm.stateMachineArn,
44+
});
45+
46+
new cdk.CfnOutput(stack, 'queueUrl', {
47+
value: queue.queueUrl,
48+
});
49+
50+
app.synth();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"version": "20.0.0",
3+
"files": {
4+
"a598966383649ea6d920222923e22b0f5e7568d4eb610c8c0a5167f4ccc2a2b5": {
5+
"source": {
6+
"path": "aws-stepfunctions-tasks-sqs-send-message-integ.template.json",
7+
"packaging": "file"
8+
},
9+
"destinations": {
10+
"current_account-current_region": {
11+
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
12+
"objectKey": "a598966383649ea6d920222923e22b0f5e7568d4eb610c8c0a5167f4ccc2a2b5.json",
13+
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
14+
}
15+
}
16+
}
17+
},
18+
"dockerImages": {}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
{
2+
"Resources": {
3+
"showmethemessagesKeyC4D56D85": {
4+
"Type": "AWS::KMS::Key",
5+
"Properties": {
6+
"KeyPolicy": {
7+
"Statement": [
8+
{
9+
"Action": "kms:*",
10+
"Effect": "Allow",
11+
"Principal": {
12+
"AWS": {
13+
"Fn::Join": [
14+
"",
15+
[
16+
"arn:",
17+
{
18+
"Ref": "AWS::Partition"
19+
},
20+
":iam::",
21+
{
22+
"Ref": "AWS::AccountId"
23+
},
24+
":root"
25+
]
26+
]
27+
}
28+
},
29+
"Resource": "*"
30+
}
31+
],
32+
"Version": "2012-10-17"
33+
},
34+
"Description": "Created by aws-stepfunctions-tasks-sqs-send-message-integ/show-me-the-messages"
35+
},
36+
"UpdateReplacePolicy": "Retain",
37+
"DeletionPolicy": "Retain"
38+
},
39+
"showmethemessages8D16BBDB": {
40+
"Type": "AWS::SQS::Queue",
41+
"Properties": {
42+
"KmsMasterKeyId": {
43+
"Fn::GetAtt": [
44+
"showmethemessagesKeyC4D56D85",
45+
"Arn"
46+
]
47+
}
48+
},
49+
"UpdateReplacePolicy": "Delete",
50+
"DeletionPolicy": "Delete"
51+
},
52+
"StateMachineRoleB840431D": {
53+
"Type": "AWS::IAM::Role",
54+
"Properties": {
55+
"AssumeRolePolicyDocument": {
56+
"Statement": [
57+
{
58+
"Action": "sts:AssumeRole",
59+
"Effect": "Allow",
60+
"Principal": {
61+
"Service": {
62+
"Fn::FindInMap": [
63+
"ServiceprincipalMap",
64+
{
65+
"Ref": "AWS::Region"
66+
},
67+
"states"
68+
]
69+
}
70+
}
71+
}
72+
],
73+
"Version": "2012-10-17"
74+
}
75+
}
76+
},
77+
"StateMachineRoleDefaultPolicyDF1E6607": {
78+
"Type": "AWS::IAM::Policy",
79+
"Properties": {
80+
"PolicyDocument": {
81+
"Statement": [
82+
{
83+
"Action": "sqs:SendMessage",
84+
"Effect": "Allow",
85+
"Resource": {
86+
"Fn::GetAtt": [
87+
"showmethemessages8D16BBDB",
88+
"Arn"
89+
]
90+
}
91+
},
92+
{
93+
"Action": [
94+
"kms:Decrypt",
95+
"kms:GenerateDataKey*"
96+
],
97+
"Effect": "Allow",
98+
"Resource": {
99+
"Fn::GetAtt": [
100+
"showmethemessagesKeyC4D56D85",
101+
"Arn"
102+
]
103+
}
104+
}
105+
],
106+
"Version": "2012-10-17"
107+
},
108+
"PolicyName": "StateMachineRoleDefaultPolicyDF1E6607",
109+
"Roles": [
110+
{
111+
"Ref": "StateMachineRoleB840431D"
112+
}
113+
]
114+
}
115+
},
116+
"StateMachine2E01A3A5": {
117+
"Type": "AWS::StepFunctions::StateMachine",
118+
"Properties": {
119+
"RoleArn": {
120+
"Fn::GetAtt": [
121+
"StateMachineRoleB840431D",
122+
"Arn"
123+
]
124+
},
125+
"DefinitionString": {
126+
"Fn::Join": [
127+
"",
128+
[
129+
"{\"StartAt\":\"send message to sqs\",\"States\":{\"send message to sqs\":{\"Next\":\"Final step\",\"Type\":\"Task\",\"Resource\":\"arn:",
130+
{
131+
"Ref": "AWS::Partition"
132+
},
133+
":states:::sqs:sendMessage\",\"Parameters\":{\"QueueUrl\":\"",
134+
{
135+
"Ref": "showmethemessages8D16BBDB"
136+
},
137+
"\",\"MessageBody\":\"sending message over\"}},\"Final step\":{\"Type\":\"Pass\",\"End\":true}},\"TimeoutSeconds\":30}"
138+
]
139+
]
140+
}
141+
},
142+
"DependsOn": [
143+
"StateMachineRoleDefaultPolicyDF1E6607",
144+
"StateMachineRoleB840431D"
145+
]
146+
}
147+
},
148+
"Outputs": {
149+
"stateMachineArn": {
150+
"Value": {
151+
"Ref": "StateMachine2E01A3A5"
152+
}
153+
},
154+
"queueUrl": {
155+
"Value": {
156+
"Ref": "showmethemessages8D16BBDB"
157+
}
158+
}
159+
},
160+
"Mappings": {
161+
"ServiceprincipalMap": {
162+
"af-south-1": {
163+
"states": "states.af-south-1.amazonaws.com"
164+
},
165+
"ap-east-1": {
166+
"states": "states.ap-east-1.amazonaws.com"
167+
},
168+
"ap-northeast-1": {
169+
"states": "states.ap-northeast-1.amazonaws.com"
170+
},
171+
"ap-northeast-2": {
172+
"states": "states.ap-northeast-2.amazonaws.com"
173+
},
174+
"ap-northeast-3": {
175+
"states": "states.ap-northeast-3.amazonaws.com"
176+
},
177+
"ap-south-1": {
178+
"states": "states.ap-south-1.amazonaws.com"
179+
},
180+
"ap-southeast-1": {
181+
"states": "states.ap-southeast-1.amazonaws.com"
182+
},
183+
"ap-southeast-2": {
184+
"states": "states.ap-southeast-2.amazonaws.com"
185+
},
186+
"ap-southeast-3": {
187+
"states": "states.ap-southeast-3.amazonaws.com"
188+
},
189+
"ca-central-1": {
190+
"states": "states.ca-central-1.amazonaws.com"
191+
},
192+
"cn-north-1": {
193+
"states": "states.cn-north-1.amazonaws.com"
194+
},
195+
"cn-northwest-1": {
196+
"states": "states.cn-northwest-1.amazonaws.com"
197+
},
198+
"eu-central-1": {
199+
"states": "states.eu-central-1.amazonaws.com"
200+
},
201+
"eu-north-1": {
202+
"states": "states.eu-north-1.amazonaws.com"
203+
},
204+
"eu-south-1": {
205+
"states": "states.eu-south-1.amazonaws.com"
206+
},
207+
"eu-south-2": {
208+
"states": "states.eu-south-2.amazonaws.com"
209+
},
210+
"eu-west-1": {
211+
"states": "states.eu-west-1.amazonaws.com"
212+
},
213+
"eu-west-2": {
214+
"states": "states.eu-west-2.amazonaws.com"
215+
},
216+
"eu-west-3": {
217+
"states": "states.eu-west-3.amazonaws.com"
218+
},
219+
"me-south-1": {
220+
"states": "states.me-south-1.amazonaws.com"
221+
},
222+
"sa-east-1": {
223+
"states": "states.sa-east-1.amazonaws.com"
224+
},
225+
"us-east-1": {
226+
"states": "states.us-east-1.amazonaws.com"
227+
},
228+
"us-east-2": {
229+
"states": "states.us-east-2.amazonaws.com"
230+
},
231+
"us-gov-east-1": {
232+
"states": "states.us-gov-east-1.amazonaws.com"
233+
},
234+
"us-gov-west-1": {
235+
"states": "states.us-gov-west-1.amazonaws.com"
236+
},
237+
"us-iso-east-1": {
238+
"states": "states.amazonaws.com"
239+
},
240+
"us-iso-west-1": {
241+
"states": "states.amazonaws.com"
242+
},
243+
"us-isob-east-1": {
244+
"states": "states.amazonaws.com"
245+
},
246+
"us-west-1": {
247+
"states": "states.us-west-1.amazonaws.com"
248+
},
249+
"us-west-2": {
250+
"states": "states.us-west-2.amazonaws.com"
251+
}
252+
}
253+
}
254+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"version":"20.0.0"}

0 commit comments

Comments
 (0)