Skip to content

Commit

Permalink
fix(sns-subscriptions): restrict encryption of queue to only the resp…
Browse files Browse the repository at this point in the history
…ective sns topic (under feature flag) (#20521)

Implements #20339 

The change adds a conditional that only the corresponding SNS Topic can decrypt the SQS queue with the KMS-Key if one was given.

----

### All Submissions:

* [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/master/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/master/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/master/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
daschaa authored Jul 8, 2022
1 parent 0aad6c9 commit 4e0c80f
Show file tree
Hide file tree
Showing 7 changed files with 358 additions and 102 deletions.
6 changes: 5 additions & 1 deletion packages/@aws-cdk/aws-sns-subscriptions/lib/sqs.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as iam from '@aws-cdk/aws-iam';
import * as sns from '@aws-cdk/aws-sns';
import * as sqs from '@aws-cdk/aws-sqs';
import { ArnFormat, Names, Stack, Token } from '@aws-cdk/core';
import { ArnFormat, FeatureFlags, Names, Stack, Token } from '@aws-cdk/core';
import * as cxapi from '@aws-cdk/cx-api';
import { Construct } from 'constructs';
import { SubscriptionProps } from './subscription';

Expand Down Expand Up @@ -55,6 +56,9 @@ export class SqsSubscription implements sns.ITopicSubscription {
resources: ['*'],
actions: ['kms:Decrypt', 'kms:GenerateDataKey'],
principals: [snsServicePrincipal],
conditions: FeatureFlags.of(topic).isEnabled(cxapi.SNS_SUBSCRIPTIONS_SQS_DECRYPTION_POLICY)
? { ArnEquals: { 'aws:SourceArn': topic.topicArn } }
: undefined,
}));
}

Expand Down
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-sns-subscriptions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
"@aws-cdk/aws-sns": "0.0.0",
"@aws-cdk/aws-sqs": "0.0.0",
"@aws-cdk/core": "0.0.0",
"@aws-cdk/cx-api": "0.0.0",
"constructs": "^10.0.0"
},
"homepage": "https://github.com/aws/aws-cdk",
Expand Down
12 changes: 10 additions & 2 deletions packages/@aws-cdk/aws-sns-subscriptions/test/integ.sns-sqs.lit.ts
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import * as kms from '@aws-cdk/aws-kms';
import * as sns from '@aws-cdk/aws-sns';
import * as sqs from '@aws-cdk/aws-sqs';
import * as cdk from '@aws-cdk/core';
import * as cxapi from '@aws-cdk/cx-api';
import * as subs from '../lib';

const restrictSqsDescryption = { [cxapi.SNS_SUBSCRIPTIONS_SQS_DECRYPTION_POLICY]: true };

class SnsToSqs extends cdk.Stack {
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);

/// !show
const topic = new sns.Topic(this, 'MyTopic');
const queue = new sqs.Queue(this, 'MyQueue');
const queue = new sqs.Queue(this, 'MyQueue', {
encryptionMasterKey: new kms.Key(this, 'EncryptionMasterKey'),
});

topic.addSubscription(new subs.SqsSubscription(queue, {
deadLetterQueue: new sqs.Queue(this, 'DeadLetterQueue'),
Expand All @@ -18,7 +24,9 @@ class SnsToSqs extends cdk.Stack {
}
}

const app = new cdk.App();
const app = new cdk.App({
context: restrictSqsDescryption,
});

new SnsToSqs(app, 'aws-cdk-sns-sqs');

Expand Down
Original file line number Diff line number Diff line change
@@ -1,110 +1,171 @@
{
"Resources": {
"MyTopic86869434": {
"Type": "AWS::SNS::Topic"
},
"MyQueueE6CA6235": {
"Type": "AWS::SQS::Queue",
"UpdateReplacePolicy": "Delete",
"DeletionPolicy": "Delete"
},
"MyQueuePolicy6BBEDDAC": {
"Type": "AWS::SQS::QueuePolicy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": "sqs:SendMessage",
"Condition": {
"ArnEquals": {
"aws:SourceArn": {
"Ref": "MyTopic86869434"
}
"Resources": {
"MyTopic86869434": {
"Type": "AWS::SNS::Topic"
},
"MyQueueE6CA6235": {
"Type": "AWS::SQS::Queue",
"UpdateReplacePolicy": "Delete",
"DeletionPolicy": "Delete",
"Properties": {
"KmsMasterKeyId": {
"Fn::GetAtt": [
"EncryptionMasterKey5BD393B9",
"Arn"
]
}
},
"Effect": "Allow",
"Principal": {
"Service": "sns.amazonaws.com"
},
"Resource": {
"Fn::GetAtt": [
"MyQueueE6CA6235",
"Arn"
]
}
}
],
"Version": "2012-10-17"
},
"Queues": [
{
"Ref": "MyQueueE6CA6235"
}
]
}
},
"MyQueueawscdksnssqsMyTopic9361DEA223429051": {
"Type": "AWS::SNS::Subscription",
"Properties": {
"Protocol": "sqs",
"TopicArn": {
"Ref": "MyTopic86869434"
},
"Endpoint": {
"Fn::GetAtt": [
"MyQueueE6CA6235",
"Arn"
]
"MyQueuePolicy6BBEDDAC": {
"Type": "AWS::SQS::QueuePolicy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": "sqs:SendMessage",
"Condition": {
"ArnEquals": {
"aws:SourceArn": {
"Ref": "MyTopic86869434"
}
}
},
"Effect": "Allow",
"Principal": {
"Service": "sns.amazonaws.com"
},
"Resource": {
"Fn::GetAtt": [
"MyQueueE6CA6235",
"Arn"
]
}
}
],
"Version": "2012-10-17"
},
"Queues": [
{
"Ref": "MyQueueE6CA6235"
}
]
}
},
"RedrivePolicy": {
"deadLetterTargetArn": {
"Fn::GetAtt": [
"DeadLetterQueue9F481546",
"Arn"
]
}
}
}
},
"DeadLetterQueue9F481546": {
"Type": "AWS::SQS::Queue",
"UpdateReplacePolicy": "Delete",
"DeletionPolicy": "Delete"
},
"DeadLetterQueuePolicyB1FB890C": {
"Type": "AWS::SQS::QueuePolicy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": "sqs:SendMessage",
"Condition": {
"ArnEquals": {
"aws:SourceArn": {
"MyQueueawscdksnssqsMyTopic9361DEA223429051": {
"Type": "AWS::SNS::Subscription",
"Properties": {
"Protocol": "sqs",
"TopicArn": {
"Ref": "MyTopic86869434"
}
},
"Endpoint": {
"Fn::GetAtt": [
"MyQueueE6CA6235",
"Arn"
]
},
"RedrivePolicy": {
"deadLetterTargetArn": {
"Fn::GetAtt": [
"DeadLetterQueue9F481546",
"Arn"
]
}
}
},
"Effect": "Allow",
"Principal": {
"Service": "sns.amazonaws.com"
},
"Resource": {
"Fn::GetAtt": [
"DeadLetterQueue9F481546",
"Arn"
}
},
"DeadLetterQueue9F481546": {
"Type": "AWS::SQS::Queue",
"UpdateReplacePolicy": "Delete",
"DeletionPolicy": "Delete"
},
"DeadLetterQueuePolicyB1FB890C": {
"Type": "AWS::SQS::QueuePolicy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": "sqs:SendMessage",
"Condition": {
"ArnEquals": {
"aws:SourceArn": {
"Ref": "MyTopic86869434"
}
}
},
"Effect": "Allow",
"Principal": {
"Service": "sns.amazonaws.com"
},
"Resource": {
"Fn::GetAtt": [
"DeadLetterQueue9F481546",
"Arn"
]
}
}
],
"Version": "2012-10-17"
},
"Queues": [
{
"Ref": "DeadLetterQueue9F481546"
}
]
}
}
],
"Version": "2012-10-17"
},
"Queues": [
{
"Ref": "DeadLetterQueue9F481546"
}
]
}
"EncryptionMasterKey5BD393B9": {
"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": "*"
},
{
"Action": [
"kms:Decrypt",
"kms:GenerateDataKey"
],
"Effect": "Allow",
"Principal": {
"Service": "sns.amazonaws.com"
},
"Condition": {
"ArnEquals": {
"aws:SourceArn": {
"Ref": "MyTopic86869434"
}
}
},
"Resource": "*"
}
],
"Version": "2012-10-17"
}
},
"DeletionPolicy": "Retain",
"UpdateReplacePolicy": "Retain"
}
}
}
}
Loading

0 comments on commit 4e0c80f

Please sign in to comment.