I've been through the AWS SNS/SQS subscription instructions multiple times, and have gone through a few different blogs and StackOverflow posts trying various things. However, no matter how many times I try to publish a message to SNS and poll/receive it from SQS, it never pops out the other side. I'm hoping it's something super obvious that I'm missing, that someone with more experience/fresher eyes than me can see.
For some background, I created both SQS and SNS in the same account. I create the subscription last after I have set the access policies for both of them. And I make sure that when I do create the subscription that I get the little green checkmark that says the subscription has been confirmed. Nothing fancy, no FIFO queue, I've set the visibility timeout to 1 minute, and receive message wait time relatively low for the queue as well. I only have in the account one SQS and one SNS, so it's not like I can mess up subscribing or giving access to the wrong ones.
For my SQS access policy this is what it looks like:
{
"Version": "2012-10-17",
"Id": "allow_sns_access_policy",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "sns.amazonaws.com"
},
"Action": "sqs:SendMessage",
"Resource": "arn:aws:sqs:us-east-1:<my_unique_id>:<name_of_my_queue>",
"Condition": {
"ArnEquals": {
"aws:SourceArn": "arn:aws:sns:us-east-1:<my_unique_id>:<name_of_my_topic>"
}
}
}
]
}
My SNS access policy is as follows:
{
"Version": "2012-10-17",
"Id": "allow_sqs_access_policy",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "sqs.amazonaws.com"
},
"Action": "sns:Subscribe",
"Resource": "arn:aws:sqs:us-east-1:<my_unique_id>:<name_of_my_topic>",
"Condition": {
"ArnEquals": {
"aws:SourceArn": "arn:aws:sns:us-east-1:<my_unique_id>:<name_of_my_queue>"
}
}
}
]
}
I make sure to copy and paste arn resources to limit spelling mistakes. I've experimented with other things, but all of them also didn't work. This to me should work but doesn't.
I guess the policies can be finicky sometimes. I attempted to remove the policies, but that didn't work even though they're in the same region. So here is what I wound up setting for the two policies to get them to correctly communicate. Maybe someone has suggestions for how to make this better, but as of right now this is what works.
SNS policy:
{
"Version": "2008-10-17",
"Id": "__default_policy_ID",
"Statement": [
{
"Sid": "__default_statement_ID",
"Effect": "Allow",
"Principal": {
"Service": "sqs.amazonaws.com"
},
"Action": [
"SNS:GetTopicAttributes",
"SNS:SetTopicAttributes",
"SNS:AddPermission",
"SNS:RemovePermission",
"SNS:DeleteTopic",
"SNS:Subscribe",
"SNS:ListSubscriptionsByTopic",
"SNS:Publish",
"SNS:Receive"
],
"Resource": "arn:aws:sns:<region>:<topic_owner>:<topic>",
"Condition": {
"StringEquals": {
"AWS:SourceOwner": "<topic_owner>"
}
}
},
{
"Sid": "s3-publish",
"Effect": "Allow",
"Principal": "*",
"Action": "sns:Publish",
"Resource": "arn:aws:sns:<region>:<topic_owner>:<topic>",
"Condition": {
"StringEquals": {
"AWS:SourceAccount": "<topic_owner>"
},
"ArnLike": {
"AWS:SourceArn": "arn:aws:s3:*:*:*"
}
}
}
]
}
SQS Policy
{
"Version": "2008-10-17",
"Id": "__default_policy_ID",
"Statement": [
{
"Sid": "__owner_statement",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<topic_owner>:root"
},
"Action": "SQS:*",
"Resource": "arn:aws:sqs:<region>:<topic_owner>:<queue_name>"
},
{
"Sid": "topic-subscription-arn:aws:sns:<region>:<topic_owner>:<topic_name>",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "SQS:SendMessage",
"Resource": "arn:aws:sqs:<region>:<topic_owner>:<queue_name>",
"Condition": {
"ArnLike": {
"aws:SourceArn": "arn:aws:sns:<region>:<topic_owner>:<topic_name>"
}
}
}
]
}
Related
I'm trying to get CloudWatch to send to my SNS topic. The topic is encrypted. However I get this error
Received error: "CloudWatch Alarms does not have authorization to access the SNS topic encryption key."
I have added KMS permissions to the access policy associated with the SNS topic but I get this error when I try to save the policy
Error code: InvalidParameter - Error message: An error occurred while setting the attribute access policy. Invalid parameter: Policy statement action out of service scope!
Is there something in the policy I am misisng?
{
"Version": "2012-10-17",
"Id": "SNS",
"Statement": [
{
"Sid": "SNSPolicy",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"SNS:GetTopicAttributes",
"SNS:SetTopicAttributes",
"SNS:AddPermission",
"SNS:RemovePermission",
"SNS:DeleteTopic",
"SNS:Subscribe",
"SNS:ListSubscriptionsByTopic",
"SNS:Publish"
],
"Resource": "arn:aws:sns:*:my-account-name:my-topic-name"
},
{
"Sid": "CloudWatch",
"Effect": "Allow",
"Principal": {
"Service": "cloudwatch.amazonaws.com"
},
"Action": [
"kms:Decrypt",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": [
"arn:aws:kms:*:my-account-name:key/*"
],
"Condition": {
"StringEquals": {
"kms:RequestAlias": "alias/my-alias-name"
}
}
}
]
}
Cloudwatch is not having necessary permission to access the KMS key which is being used by the SNS topic.
Below SNS topic access policy will give access to the Amazon cloudwatch events.
{
"Version": "2012-10-17",
"Id": "__default_policy_ID",
"Statement": [
{
"Sid": "__default_statement_ID",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"SNS:GetTopicAttributes",
"SNS:SetTopicAttributes",
"SNS:AddPermission",
"SNS:RemovePermission",
"SNS:DeleteTopic",
"SNS:Subscribe",
"SNS:ListSubscriptionsByTopic",
"SNS:Publish"
],
"Resource": "arn:aws:sns:<region>:<account>:<snstopic>",
"Condition": {
"StringEquals": {
"AWS:SourceOwner": "<account>"
}
}
},
{
"Sid": "AWSEvents_test_Id10633056916634",
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Action": "sns:Publish",
"Resource": "arn:aws:sns:<region>:<account>:<snstopic>"
}
]
}
Below customer managed KMS key policy, it will give access to Amazon cloudwatch event source.
{
"Version": "2012-10-17",
"Id": "key-consolepolicy-3",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<account>:<iamuser>",
"Service": "cloudwatch.amazonaws.com"
},
"Action": "kms:*",
"Resource": "*"
}
]
}
Several AWS services publish events to Amazon SNS topics. To know more, Kindly refer here
I want to restrict my sqs to accept only from event-bridge rule, below IAM rule looks correct with deny in place, but sqs not receiving message with this, any input appreciated.
{ "Id": "Policy", "Version": "2012-10-17", "Statement": [
{
"Sid": "sid",
"Action": [
"sqs:SendMessage"
],
"Effect": "Deny",
"Resource": "arn:aws:sqs:us-east-1:***:sri-test-queue-3",
"Condition": {
"ArnNotEquals": {
"aws:SourceArn": "arn:aws:events:us-east-1:***:rule/sri-test-bus/sri-test-sqs-rule"
}
},
"Principal": "*"
} ] }
The one generated by Event-bridge to allow sqs access looks like this
{
"Version": "2008-10-17",
"Id": "__default_policy_ID",
"Statement": [
{
"Sid": "AWSEvents_sri-test-sqs-rule_Id12",
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Action": "sqs:SendMessage",
"Resource": "arn:aws:sqs:us-east-1:***:sri-test-queue-3",
"Condition": {
"ArnEquals": {
"aws:SourceArn": "arn:aws:events:us-east-1:***:rule/sri-test-bus/sri-test-sqs-rule"
}
}
}
]
}
Use the bottom policy. SQS policy denies by default, so you do not need to worry about other resources posting messages to SQS. The policy would allow only arn:aws:events:us-east-1:***:rule/sri-test-bus/sri-test-sqs-rule to send the messages.
The problem with the policy statement you wrote was that you did not have an "Allow" statement, so SQS is denying SendMessage actions from every source.
We just had to put some combination of principalTypes to achieve this, below one worked finally
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ownerstatement",
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Action": "sqs:SendMessage",
"Resource": "arn:aws:sqs:us-east-1:xxxx:sri-test-queue-3"
},
{
"Sid": "DenyAllExceptBus",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "sqs:SendMessage",
"Resource": "arn:aws:sqs:us-east-1:xxxx:sri-test-queue-3",
"Condition": {
"ArnNotEquals": {
"aws:SourceArn": [
"arn:aws:events:us-east-1:xxxx:rule/sri-test-bus/sri-test-sqs-rule"
]
}
}
}
]
}
I have a AWS S3 bucket in account A, This bucket was created by AWS Control Tower.
And used for collecting logs from all other account in my org,
I was trying to understand the bucket policy which is something like this
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSSLRequestsOnly",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::aws-controltower-logs-12345656-us-east-1",
"arn:aws:s3:::aws-controltower-logs-12345656-us-east-1/*"
],
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
}
},
{
"Sid": "AWSBucketPermissionsCheck",
"Effect": "Allow",
"Principal": {
"Service": [
"config.amazonaws.com",
"cloudtrail.amazonaws.com"
]
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::aws-controltower-logs-12345656-us-east-1"
},
{
"Sid": "AWSConfigBucketExistenceCheck",
"Effect": "Allow",
"Principal": {
"Service": [
"config.amazonaws.com",
"cloudtrail.amazonaws.com"
]
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::aws-controltower-logs-12345656-us-east-1"
},
{
"Sid": "AWSBucketDelivery",
"Effect": "Allow",
"Principal": {
"Service": [
"config.amazonaws.com",
"cloudtrail.amazonaws.com"
]
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::aws-controltower-logs-12345656-us-east-1/o-1234/AWSLogs/*/*"
}
]
}
Now all other account in my org are able to dump there cloudtrail logs within this S3.
But i dont get one thing, i did not specified any particular or individual account number, but still other accounts are able to write content in this bucket,
Although i do see the principal which mentions relevant service name that can dump, but should,nt it only for this account itself ?
Let's analyze the rules one by one:
The first rule only says that no access without SSL is possible, it does nothing if SSL layer is present:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSSLRequestsOnly",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::aws-controltower-logs-12345656-us-east-1",
"arn:aws:s3:::aws-controltower-logs-12345656-us-east-1/*"
],
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
}
},
The next two actions allow only read:
{
"Sid": "AWSBucketPermissionsCheck",
"Effect": "Allow",
"Principal": {
"Service": [
"config.amazonaws.com",
"cloudtrail.amazonaws.com"
]
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::aws-controltower-logs-12345656-us-east-1"
},
{
"Sid": "AWSConfigBucketExistenceCheck",
"Effect": "Allow",
"Principal": {
"Service": [
"config.amazonaws.com",
"cloudtrail.amazonaws.com"
]
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::aws-controltower-logs-12345656-us-east-1"
},
So the only action which allows any writing is this one:
{
"Sid": "AWSBucketDelivery",
"Effect": "Allow",
"Principal": {
"Service": [
"config.amazonaws.com",
"cloudtrail.amazonaws.com"
]
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::aws-controltower-logs-12345656-us-east-1/o-1234/AWSLogs/*/*"
}
]
}
And it says the following: You can put object under /o-1234/AWSLogs as long as you are one of the following two AWS services: Config or Cloudtrail.
Clearly, if knowing the bucket name and the org ID allows me to persuade Config or Cloudtrail to use that bucket I cannot see anything what would stop me from doing that except from some internal protection inside those services.
Based on this document:
https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-set-bucket-policy-for-multiple-accounts.html
It seems that for allowing an account 111111111111 to write to that bucket you should use the following ARN pattern: "arn:aws:s3:::myBucketName/optionalLogFilePrefix/AWSLogs/111111111111/*",
So while the answer provided by #izayoi does not provide any explanation, it is still correct. Cloudtrail service should guarantee you that it will always use that account id in the log, so you can narrow down the access by listing all your account numbers. Of course, it must be updated with every each new account.
Conclusion: Yes, knowing the bucket name and your organization ID should allow every AWS account in the world to use your bucket for Cloudtrail logging with the current policy...interesting. I would probably go with listing your account numbers.
"Resource": "arn:aws:s3:::aws-controltower-logs-12345656-us-east-1/o-1234/AWSLogs/*/*"
The 1st "*" enables all account numbers.
I am struggling with the setting up an S3 policy to give access to Application Load Balancer to push logs.
{
"Id": "Policy1629585161607",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1629585158642",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::S3bucketname/*",
"Principal": {
"AWS":"arn:aws:iam:LoadBalancerId:root"
}
}
]
}
The LoadBalancerIdcame from the last part of the loan balancer's ARN; follows the trailing slash after the load balancer's name in the ARN.
The error got from S3 is Invalid principal in policy, what have I done wrong?
The AWS docs explain well what the policy should be exactly. Sadly, your policy is incorrect. It should follow the following format:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::elb-account-id:root"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::bucket-name/prefix/AWSLogs/your-aws-account-id/*"
},
{
"Effect": "Allow",
"Principal": {
"Service": "delivery.logs.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::bucket-name/prefix/AWSLogs/your-aws-account-id/*",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
},
{
"Effect": "Allow",
"Principal": {
"Service": "delivery.logs.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::bucket-name"
}
]
}
On top of that, bucket must be in same region and be encrypted.
I want to create an AWS Elasticsearch with this policy, to enable specific access from IAM roles, set admin IPs, and public read only. ES Console keeps returning an error "Error setting policy". I can't work out why this would not be allowed?
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<id>:role/<lambda role 1 name>"
},
"Action": "es:ESHttpPost",
"Resource": "arn:aws:es:eu-west-1:<id>:domain/*/*"
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<id>:role/<lambda role 2 name>"
},
"Action": "es:ESHttpDelete",
"Resource": "arn:aws:es:eu-west-1:<id>:domain/*/*"
},
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "es:*",
"Resource": "arn:aws:es:eu-west-1:<id>:domain/*/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"<ip1>",
"<ip2>",
"<ip3>"
]
}
}
},
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "es:ESHttpGet",
"Resource": "arn:aws:es:eu-west-1:<id>:domain/*/*"
}
]
}
It's in eu-west-1 and version 7.1. I've tried variations like es:* and putting principals in an array (like in the provided templates) but these are all rejected?! I can seemingly only have 2 statements, with 1 principal in each (* and 1 of these IAMs).
Is there a better recommended way? Like putting it behind API Gateway or something. I saw reverse proxy in the docs but this seems like a ridiculous overkill and $$$.