How to grant SNS topic permission to write to SQS queue in javascript (v3 API)?

0

As subject, I've been struggling with this all day and can't find a solution.

I have a SNS topic, and a SQS queue subscribed to it. Creation of both, and the subscription, is done programatically using the v3 javascript SDK. I can see the two resources and the subscription in the console.

When I write to the topic, nothing appears on the queue (polled from the console). The queue access policy looks like this:

{
  "Version": "2012-10-17",
  "Id": "arn:aws:sqs:eu-west-1:98xxxxx8745:nocodebots/SQSDefaultPolicy"
}

If I select the subscription in the console (SNS Subscription) and click the "Subscribe to AmazonSNS topic" button, the access policy changes to this:

{
  "Version": "2012-10-17",
  "Id": "arn:aws:sqs:eu-west-1:98xxxxx8745:undefined/SQSDefaultPolicy",
  "Statement": [
    {
      "Sid": "topic-subscription-arn:aws:sns:eu-west-1:98xxxxx8745:nocodebots",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "SQS:SendMessage",
      "Resource": "arn:aws:sqs:eu-west-1:98xxxxx8745:nocodebots",
      "Condition": {
        "ArnLike": {
          "aws:SourceArn": "arn:aws:sns:eu-west-1:98xxxxx8745:nocodebots"
        }
      }
    }
  ]
}

Everything now works - messages posted to the topic are routed to the queue.

So I assume I need to give the SNS Topic permission to write to the SQS queue. I'm also assuming I need to create a policy to do this, but it seems I need my Account ID in the policy. Is this necessary, given that I have Arns for the Topic and Queue and the QueueUrls?? The same piece of code, in the same context builds both, and the subscription is successful, so surely I have everything to also grant the permission at the same time?

Scratching my head!

David

2개 답변
1

Hi, it is necessary know the account in order that the policy executes over the right resource, here there are documentation related with IAM and the SNS policies management https://docs.aws.amazon.com/sns/latest/dg/SendMessageToHttp.iam.permissions.html

The idea when you use a policy is to make it the most granular possible, and for doing that the policy have to know exactly were the resources are, for that reason is the use of the ID account.

Additionally, if you have a case that you use more than 1 account (is very common), make a cross policy is possible also when you define the account ID.

I will share with you some tools that you could use to create policies: https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/create-policy.html#examples https://awspolicygen.s3.amazonaws.com/policygen.html

AWS
답변함 9달 전
1

Gool, thanks :) Now I see how it fits together.

I solved it with the policy below, using the topic Arn rather than the account ID:

let response;
let topicArn = getTopic('topic_name');             // my own function, returns topic Arn
let queue = getQueueUrlAndArn('queue_name');   // my own function, returns { Arn: 'xxxx', Url: 'yyyy' }

// give the topic permission to write to the queue
let policy = {
    "Version": "2012-10-17",
    "Id": "Write_Launch_Queue_Policy",
    "Statement": {
         "Sid":"Write_Launch_Queue_Statement",
        "Effect": "Allow",
        "Principal": { "Service": "sns.amazonaws.com" },
        "Condition": { "ArnLike": { "aws:sourceArn": topicArn } },
        "Action": "sqs:SendMessage",
        "Resource": queue.Arn
    }
};

response = await this.#sqsClient.send(new SetQueueAttributesCommand({ QueueUrl: queue.Url, Attributes: { Policy: JSON.stringify(policy) } }));

// now subscribe the queue to the topic
response = await this.#snsClient.send(new SubscribeCommand({ TopicArn: topicArn, Protocol: 'sqs', Endpoint: queue.Arn, ReturnSubscriptionArn: false}));

From what I can work out, this only gives the specified Topic permission to write to the specified Queue, nice and tight.

All the best,

David

dmb0058
답변함 9달 전

로그인하지 않았습니다. 로그인해야 답변을 게시할 수 있습니다.

좋은 답변은 질문에 명확하게 답하고 건설적인 피드백을 제공하며 질문자의 전문적인 성장을 장려합니다.

질문 답변하기에 대한 가이드라인

관련 콘텐츠