Skip to content

Commit

Permalink
fix(stepfunctions-tasks): SqsSendMessage is missing KMS permissions (#…
Browse files Browse the repository at this point in the history
…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*
  • Loading branch information
jesterhazy authored Jul 5, 2022
1 parent 7f4f150 commit 52b7019
Show file tree
Hide file tree
Showing 7 changed files with 737 additions and 0 deletions.
10 changes: 10 additions & 0 deletions packages/@aws-cdk/aws-stepfunctions-tasks/lib/sqs/send-message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,16 @@ export class SqsSendMessage extends sfn.TaskStateBase {
resources: [this.props.queue.queueArn],
}),
];

// sending to an encrypted queue requires
// permissions on the associated kms key
if (this.props.queue.encryptionMasterKey) {
this.taskPolicies.push(
new iam.PolicyStatement({
actions: ['kms:Decrypt', 'kms:GenerateDataKey*'],
resources: [this.props.queue.encryptionMasterKey.keyArn],
}));
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import * as sqs from '@aws-cdk/aws-sqs';
import * as sfn from '@aws-cdk/aws-stepfunctions';
import * as cdk from '@aws-cdk/core';
import { SqsSendMessage } from '../../lib/sqs/send-message';

/*
* Creates a state machine with a task state to send a message to an SQS
* queue.
*
* When the state machine is executed, it will send a message to our
* queue, which can subsequently be consumed.
*
* Stack verification steps:
* The generated State Machine can be executed from the CLI (or Step Functions console)
* and runs with an execution status of `Succeeded`.
*
* -- aws stepfunctions start-execution --state-machine-arn <state-machine-arn-from-output> provides execution arn
* -- aws stepfunctions describe-execution --execution-arn <from previous command> returns a status of `Succeeded`
* -- aws sqs receive-message --queue-url <queue-url-from-output> has a message of 'sending message over'
*/
const app = new cdk.App();
const stack = new cdk.Stack(app, 'aws-stepfunctions-tasks-sqs-send-message-integ');
const queue = new sqs.Queue(stack, 'show-me-the-messages', {
encryption: sqs.QueueEncryption.KMS,
});

const sendMessageTask = new SqsSendMessage(stack, 'send message to sqs', {
queue,
messageBody: sfn.TaskInput.fromText('sending message over'),
});

const finalStatus = new sfn.Pass(stack, 'Final step');

const chain = sfn.Chain.start(sendMessageTask)
.next(finalStatus);

const sm = new sfn.StateMachine(stack, 'StateMachine', {
definition: chain,
timeout: cdk.Duration.seconds(30),
});

new cdk.CfnOutput(stack, 'stateMachineArn', {
value: sm.stateMachineArn,
});

new cdk.CfnOutput(stack, 'queueUrl', {
value: queue.queueUrl,
});

app.synth();
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"version": "20.0.0",
"files": {
"a598966383649ea6d920222923e22b0f5e7568d4eb610c8c0a5167f4ccc2a2b5": {
"source": {
"path": "aws-stepfunctions-tasks-sqs-send-message-integ.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "a598966383649ea6d920222923e22b0f5e7568d4eb610c8c0a5167f4ccc2a2b5.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
}
},
"dockerImages": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
{
"Resources": {
"showmethemessagesKeyC4D56D85": {
"Type": "AWS::KMS::Key",
"Properties": {
"KeyPolicy": {
"Statement": [
{
"Action": "kms:*",
"Effect": "Allow",
"Principal": {
"AWS": {
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":iam::",
{
"Ref": "AWS::AccountId"
},
":root"
]
]
}
},
"Resource": "*"
}
],
"Version": "2012-10-17"
},
"Description": "Created by aws-stepfunctions-tasks-sqs-send-message-integ/show-me-the-messages"
},
"UpdateReplacePolicy": "Retain",
"DeletionPolicy": "Retain"
},
"showmethemessages8D16BBDB": {
"Type": "AWS::SQS::Queue",
"Properties": {
"KmsMasterKeyId": {
"Fn::GetAtt": [
"showmethemessagesKeyC4D56D85",
"Arn"
]
}
},
"UpdateReplacePolicy": "Delete",
"DeletionPolicy": "Delete"
},
"StateMachineRoleB840431D": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": {
"Fn::FindInMap": [
"ServiceprincipalMap",
{
"Ref": "AWS::Region"
},
"states"
]
}
}
}
],
"Version": "2012-10-17"
}
}
},
"StateMachineRoleDefaultPolicyDF1E6607": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": "sqs:SendMessage",
"Effect": "Allow",
"Resource": {
"Fn::GetAtt": [
"showmethemessages8D16BBDB",
"Arn"
]
}
},
{
"Action": [
"kms:Decrypt",
"kms:GenerateDataKey*"
],
"Effect": "Allow",
"Resource": {
"Fn::GetAtt": [
"showmethemessagesKeyC4D56D85",
"Arn"
]
}
}
],
"Version": "2012-10-17"
},
"PolicyName": "StateMachineRoleDefaultPolicyDF1E6607",
"Roles": [
{
"Ref": "StateMachineRoleB840431D"
}
]
}
},
"StateMachine2E01A3A5": {
"Type": "AWS::StepFunctions::StateMachine",
"Properties": {
"RoleArn": {
"Fn::GetAtt": [
"StateMachineRoleB840431D",
"Arn"
]
},
"DefinitionString": {
"Fn::Join": [
"",
[
"{\"StartAt\":\"send message to sqs\",\"States\":{\"send message to sqs\":{\"Next\":\"Final step\",\"Type\":\"Task\",\"Resource\":\"arn:",
{
"Ref": "AWS::Partition"
},
":states:::sqs:sendMessage\",\"Parameters\":{\"QueueUrl\":\"",
{
"Ref": "showmethemessages8D16BBDB"
},
"\",\"MessageBody\":\"sending message over\"}},\"Final step\":{\"Type\":\"Pass\",\"End\":true}},\"TimeoutSeconds\":30}"
]
]
}
},
"DependsOn": [
"StateMachineRoleDefaultPolicyDF1E6607",
"StateMachineRoleB840431D"
]
}
},
"Outputs": {
"stateMachineArn": {
"Value": {
"Ref": "StateMachine2E01A3A5"
}
},
"queueUrl": {
"Value": {
"Ref": "showmethemessages8D16BBDB"
}
}
},
"Mappings": {
"ServiceprincipalMap": {
"af-south-1": {
"states": "states.af-south-1.amazonaws.com"
},
"ap-east-1": {
"states": "states.ap-east-1.amazonaws.com"
},
"ap-northeast-1": {
"states": "states.ap-northeast-1.amazonaws.com"
},
"ap-northeast-2": {
"states": "states.ap-northeast-2.amazonaws.com"
},
"ap-northeast-3": {
"states": "states.ap-northeast-3.amazonaws.com"
},
"ap-south-1": {
"states": "states.ap-south-1.amazonaws.com"
},
"ap-southeast-1": {
"states": "states.ap-southeast-1.amazonaws.com"
},
"ap-southeast-2": {
"states": "states.ap-southeast-2.amazonaws.com"
},
"ap-southeast-3": {
"states": "states.ap-southeast-3.amazonaws.com"
},
"ca-central-1": {
"states": "states.ca-central-1.amazonaws.com"
},
"cn-north-1": {
"states": "states.cn-north-1.amazonaws.com"
},
"cn-northwest-1": {
"states": "states.cn-northwest-1.amazonaws.com"
},
"eu-central-1": {
"states": "states.eu-central-1.amazonaws.com"
},
"eu-north-1": {
"states": "states.eu-north-1.amazonaws.com"
},
"eu-south-1": {
"states": "states.eu-south-1.amazonaws.com"
},
"eu-south-2": {
"states": "states.eu-south-2.amazonaws.com"
},
"eu-west-1": {
"states": "states.eu-west-1.amazonaws.com"
},
"eu-west-2": {
"states": "states.eu-west-2.amazonaws.com"
},
"eu-west-3": {
"states": "states.eu-west-3.amazonaws.com"
},
"me-south-1": {
"states": "states.me-south-1.amazonaws.com"
},
"sa-east-1": {
"states": "states.sa-east-1.amazonaws.com"
},
"us-east-1": {
"states": "states.us-east-1.amazonaws.com"
},
"us-east-2": {
"states": "states.us-east-2.amazonaws.com"
},
"us-gov-east-1": {
"states": "states.us-gov-east-1.amazonaws.com"
},
"us-gov-west-1": {
"states": "states.us-gov-west-1.amazonaws.com"
},
"us-iso-east-1": {
"states": "states.amazonaws.com"
},
"us-iso-west-1": {
"states": "states.amazonaws.com"
},
"us-isob-east-1": {
"states": "states.amazonaws.com"
},
"us-west-1": {
"states": "states.us-west-1.amazonaws.com"
},
"us-west-2": {
"states": "states.us-west-2.amazonaws.com"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"version":"20.0.0"}
Loading

0 comments on commit 52b7019

Please sign in to comment.