19

I'm using the AWS SQS service, and I'm having a hard time defining permissions on my SQS queue. In my setup I'm using the AWS Lambda service, which is triggered when an object is pushed onto an S3 bucket.

However to keep my question briefly, this is what I want to achieve:

  1. Object is pushed to a S3 bucket
  2. S3 bucket triggers AWS Lambda
  3. Lambda does some calculations, and push an event to my SQS queue (Permission needs to be defined)
  4. Application reads from SQS

As you can read from previous use-case, I want my AWS Lambda method to be the only application, which can send a message to the SQS queue. I've tried to set a principal and a condition "sourceArn". But none of them work..

enter image description here

Can anyone help?

Steffen Opel
  • 63,899
  • 11
  • 192
  • 211
Cédric Verstraeten
  • 574
  • 1
  • 4
  • 15

2 Answers2

22

I don't think the SourceArn field gets populated by Lambda. I know SourceArn works for SNS, but Lambda is really running arbitrary code, not an AWS feature like SNS.

As an alternative, you can attach a policy to the IAM Role your Lambda function runs as.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1440529349000",
            "Effect": "Allow",
            "Action": [
                "sqs:SendMessage"
            ],
            "Resource": [
                "arn:aws:sqs:us-west-2:123456789012:test-queue"
            ]
        }
    ]
}

This method does not require a policy directly attached to the queue.

James
  • 11,721
  • 2
  • 35
  • 41
1

You may also specify SQS access policy which denies sending messages except your lambda

{
  "Version": "2008-10-17",
  "Statement": [
    {
      "Sid": "Only API Gateway is allowed to send messages",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "SQS:SendMessage",
      "Resource": "arn:aws:sqs:eu-west-1:XXX:my_sqs_queue",
      "Condition": {
        "StringNotLike": {
          "aws:userid": [
            "AROA4XB7NRHNVE2XY7ABC:*"
          ]
        }
      }
    }
  ]
}

by providing wildcard Principal * with condition key aws:userid for the role id. Following things need to be specified in the condition clause

<USER ID of the Role being used by the Lambda:*>

User id of the role AROA4XB7NRHNVE2XY7ABC can be retrieved using the following CLI command

aws iam get-role --role-name my_lambda_role

{
    "Role": {
       "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Action": "sts:AssumeRole",
                    "Principal": {
                        "Service": "lambda.amazonaws.com"
                    },
                    "Effect": "Allow",
                    "Sid": ""
                }
            ]
        },
        "RoleId": "AROA4XB7NRHNWU35SVABC",
        "CreateDate": "2020-01-21T11:40:55Z",
        "RoleName": "my_lambda_role",
        "Path": "/",
        "Arn": "arn:aws:iam::XXX:role/my_lambda_role"
    }
}

More info regarding this case cound be found here

kcala
  • 21
  • 2