AWS Cloudwatch can not publish to SNS Topic with SSE - amazon-web-services

I have a Route53 health check, which submits its metrics into Cloudwatch, and finally Cloudwatch specifies thresholds and should send alerts through SNS.
However, I would like my SNS Topic to be encrypted. When I turn on SNS Topic encryption using the alias/aws/sns key I receive these messages in the Cloudwatch message history:
{
"actionState": "Failed",
"stateUpdateTimestamp": 123456778899,
"notificationResource": "arn:aws:sns:xx-region-y:zzzzzzzzzz:topic_name",
"publishedMessage": null,
"error": "null (Service: AWSKMS; Status Code: 400; Error Code: AccessDeniedException; Request ID: ccccccccccccccccccc)"
}
This appears to not be an IAM issue with Cloudwatch, but with SNS itself being unauthorized to use the KMS resources.
I enjoy using the IAM Policy Simulator for IAM users to identify where their permissions are lacking, but there doesn't seem to be a way to validate a Service's access to other services. Is that a thing I can manage?
https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_testing-policies.html
I have also tried this with a CMK with the following policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "sns.amazonaws.com"
},
"Action": [
"kms:GenerateDataKey*",
"kms:Decrypt"
],
"Resource": "*"
},
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "route53.amazonaws.com"
},
"Action": [
"kms:GenerateDataKey*",
"kms:Decrypt"
],
"Resource": "*"
},
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Action": [
"kms:GenerateDataKey*",
"kms:Decrypt"
],
"Resource": "*"
},
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::XXXXXXXX:role/OrganizationAccountAccessRole"
},
"Action": "kms:*",
"Resource": "*"
}
]
}
I'm pretty much throwing darts at a wall with the principals, but I think there's validation for sns.amazonaws.comfor SNS and events.amazonaws.com for Cloudwatch.
I received the exact same error, "null (Service: AWSKMS; Status Code: 400; Error Code: AccessDeniedException; Request ID: ccccccccccccccccccc)", when using a CMK in this manner as well. I can understand my CMK not working properly, but the Amazon managed key I think should just work out of the box.
I've tried using a CMK which grants sns.amazonaws.com and events.amazonaws.com with kms:* permissions. Same error.

Just summarizing the correct answer here because the accepted answer seems to be outdated:.
You cannot use the Amazon managed CMK alias/aws/sns because in order to connect cloudwatch with an SNS topic encrypted with a KMS CMK, you need to set a resource-policy/access-policy on the CMK so that cloudwatch service can perform kms:GenerateDataKey* and kms:Decrypt actions on the key and the access-policy on amazon managed keys cannot be edited.
For your case, you would need to create a customer managed symmetric CMK, and edit the access-policy to allow cloudwatch service principal to access that CMK. The access-policy will look like:
"Version": "2012-10-17",
"Id": "key-policies",
"Statement": [
{
"Sid": "Enable IAM User Permissions for administration of this key",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxxxxxxxxx:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow cloudwatch metric to use this key",
"Effect": "Allow",
"Principal": {
"Service": "cloudwatch.amazonaws.com"
},
"Action": [
"kms:Decrypt",
"kms:GenerateDataKey*"
],
"Resource": "*"
}
]
}

Update: It's likely this information is out of date. Please try the other answers and let everyone know if they work for you.
Apparently, CloudWatch can't send messages to encrypted SNS topics according to Protecting Amazon SNS Data Using Server-Side Encryption (SSE) and AWS KMS:
Currently, CloudWatch alarms don't work with Amazon SNS encrypted topics. For information about publishing alarms to unencrypted topics, see Using Amazon CloudWatch Alarms in the Amazon CloudWatch User Guide.
However, the blog post Encrypting messages published to Amazon SNS with AWS KMS seems to indicate you can...
🤦

The service is not "events.amazonaws.com", it is "cloudwatch.amazonaws.com". You should get the SNS notifications once you change this in the key policy.
See https://docs.aws.amazon.com/sns/latest/dg/sns-server-side-encryption.html for more information.

While some AWS services use an IAM Role in your account, others use a specific principal to be granted access instead. See https://aws.amazon.com/blogs/compute/encrypting-messages-published-to-amazon-sns-with-aws-kms/.
I think in your case you need to allow the cloudwatch principal, events.amazonaws.com, to be allowed to use the KMS key you specified, in the key's policy. See the section "Enabling compatibility between encrypted topics and event sources" in the above link.
Note that as the document says, "Several AWS services publish events to Amazon SNS topics. To allow these event sources to work with encrypted topics, you must first create a customer-managed CMK and then add the following statement to the policy of the CMK." This only works with customer managed keys.

Adding just the below events.amazon.com permissions to the KMS key's resource policy did the trick for me, specifically to allow AWS::Events::Rule that had encrypted SNS topics registered as Targets for 'FAILED' CodeBuild and CodePipeline states.
{
"Sid": "Allow Events use of key (for publishing to CMK encrypted SNS topics)",
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Action": [
"kms:Decrypt",
"kms:GenerateDataKey*"
],
"Resource": "*"
}
Hope this saves someone else some of the frustration and time this had caused me.

I ran into the same issue today! I see there are suggestions for granting the CMK to cloudwatch.amazonaws.com and also to events.amazonaws.com. For me, I needed to grant to both for that to work. Here is the entirety of my Cloudformation definition for the CMK.
InternalSNSKey:
Type: AWS::KMS::Key
Properties:
Description: IA-Internal-SNS Encryption Key
KeyPolicy:
Version: 2012-10-17
Id: allow-root-access-to-key
Statement:
- Sid: allow-root-to-delegate-actions
Effect: Allow
Principal:
AWS: !Sub arn:aws:iam::${AWS::AccountId}:root
Action:
- kms:*
Resource: '*'
- Sid: allow-cloudwatch-to-use-key
Effect: Allow
Principal:
Service: cloudwatch.amazonaws.com
Action:
- kms:Decrypt
- kms:GenerateDataKey*
Resource: '*'
- Sid: allow-events-to-use-key
Effect: Allow
Principal:
Service: events.amazonaws.com
Action:
- kms:Decrypt
- kms:GenerateDataKey*
Resource: '*'

Related

Attach IAM Policy to SNS Topic

I am trying deliver a message from an unencrypted SNS topic to an encrypted SQS queue following this guide. I was able to complete the "Configure KMS permissions for AWS services" step, but I am having trouble with the "Configure KMS permissions for producers
" step. I have created the IAM role, however attaching this role to my SNS topic is where I am specifically confused. Here are some questions I have which my own research was unable to answer:
Can an IAM role be attached to a specific item (SNS topic, SQS queue, etc...)? If not, what other way is there to grant permissions to a specific item?
When the instructions mention "producer", is this referring to the SNS topic or the AWS account which owns the SNS topic?
Any and all help is greatly appreciated.
Edit:
Here is my current AWS KMS key policy:
{
"Version": "2012-10-17",
"Id": "key-consolepolicy-3",
"Statement": [
{
"Sid": "Allow administration of the key",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::${aws_account_id}:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow SNS to use KMS",
"Effect": "Allow",
"Principal": {
"Service": "sns.amazonaws.com"
},
"Action": [
"kms:GenerateDataKey",
"kms:Decrypt"
],
"Resource": "*"
}
]
}
Whenever I add the following statements to my KMS key policy in the Statement list, I get the error "MalformedPolicyDocumentException - Policy contains a statement with no principal":
{
"Effect": "Allow",
"Action": [
"kms:GenerateDataKey",
"kms:Decrypt"
],
"Resource": "${kms_customer_managed_key_arn}"
},
{
"Effect": "Allow",
"Action": [
"sqs:SendMessage"
],
"Resource": "${sqs_queue_arn}"
}
If not, what other way is there to grant permissions to a specific item?
The permissons from the link are attached to your KMS CMK key policy.
When the instructions mention "producer", is this referring to the SNS topic or the AWS account which owns the SNS topic?
The producer is anyone or anything that sends messages. It can be a lambda function, an ec2 instance or IAM user/role. In that case you give the producer permissions to sendMessage and use the KMS key. For lambda it would be in lambda execution role, for instance it would be in an instance role.

AWS SNS: Edit text messaging preferences

I am trying to enable SMS message delivery logs in AWS SNS. But no matter what I do I get this error:
Couldn't set text messaging attributes. Error code: AuthorizationError
- Error message: You are not authorized to perform actions for the provided bucket
I have tried numerous IAM roles (including admin access role) and I am logged in as the root account owner.
What might I be missing? What can I try?
Thank you!
I found this specific documentation that solved it for me: https://docs.aws.amazon.com/sns/latest/dg/sms_stats_usage.html#example_bucket_policy
The key is that the bucket policy needs to list sns.amazonaws.com as the principal, and really only needs to allow these 3 actions to finish configuring SMS:
s3:GetBucketLocation
s3:ListBucket
s3:PutObject
{
"Version": "2012-10-17",
"Id": "Policy1653549854620",
"Statement": [
{
"Sid": "Stmt1653549853470",
"Effect": "Allow",
"Principal": {
"Service": "sns.amazonaws.com"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::BUCKETNAME"
}
]
}

AWS EKS - Create cluster minimum IAM permissions (AccessDenied)

Does anyone know what should be the minimum IAM permissions that would allow a user creating an EKS cluster?
I'm assuming a role to just create a cluster with Terraform and that role has got the following statements in its policy defined (nothing more than that):
{
"Sid": "AllowEKSCreate",
"Effect": "Allow",
"Action": [
"eks:List*",
"eks:Describe*",
"eks:CreateCluster",
"ec2:Describe*"
],
"Resource": "*"
},
{
"Sid": "AllowEKSAll",
"Effect": "Allow",
"Action": "eks:*",
"Resource": "arn:aws:eks:eu-west-1:XXXXXXXXXX:cluster/my-cluster"
}
In CloudTrail I'am only seeing:
AWS access key: XXXXXXXX
AWS region: eu-west-1
Error code: AccessDenied
Event ID: XXXXXXXX
Event name: CreateCluster
Event source: eks.amazonaws.com
Successful events:
sts:GetCallerIdentity
ec2:DescribeAccountAttributes
No other event is present in CloudTrail that would be unsuccessful.
Found it!
The missing permission was iam:PassRole on the Cluster IAM Role resource.
For some reason CloudTrail does not reveal that information :(
P.S.
I think I made my question very clear so am wondering why someone would give me -1.

Defining two statements for the action on an IAM role

Is it possible, to have two statements for the same action in an IAM role?
For different actions, it works fine, but when creating a new statement for the same actions it's not working.
Example:
IamDeploymentRole:
Type: "AWS::IAM::Role"
Properties:
RoleName: "iam-deployment"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
AWS:
- !Sub "arn:aws:iam::${ManagementAccountID}:root"
Action:
- "sts:AssumeRole"
Condition:
IpAddress:
X
- Effect: "Allow"
Principal:
Service:
- "some service"
Action:
- "sts:AssumeRole"
I'm trying to do it, but it's like the second item on the statement is being ignored. I don't know how exactly this filter works.
For instance, when a statement matches the action but not the condition, does it moves on? or in the first know no it stops?
I tried a lot of documentation, but couldn't find an answer.
Condition:
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html
Condition Operator:
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_ARN
Condition Key:
https://docs.aws.amazon.com/IAM/latest/UserGuide/list_awscloudformation.html#awscloudformation-aws_ResourceTag___TagKey_
Global condition key:
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-principalarn
Polices and Permissions: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html
It appears that you are defining AssumeRolePolicyDocument, which is the Trust Policy for an IAM Role.
I tested this by creating an IAM Role with a Trust Policy that trusted both Amazon EC2 and AWS Lambda:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
},
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
I then assigned Amazon S3 permissions to the role.
Testing:
EC2: I attempted to launch an Amazon EC2 instance with this role, but the role did not appear in the drop-down list.
Lambda: I was able to successfully attach the role to an AWS Lambda function and access Amazon S3.
I then swapped the order of the trust relationships:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
},
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
This had no impact — Lambda worked fine, but EC2 would not recognize the role.
I then removed Lambda from the Trust Relationship:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
This caused the role to disappear from the Lambda console and, strangely, it also did not appear for use in the EC2 console.
I then created an identical role (with just EC2 as the trusted entity) and it worked fine.
Bottom line: The services do seem to get confused when there are multiple services in the Trust Policy. It is almost as if it "remembers" the first service and ignores the others, even when the trust policy is modified. Therefore, it seems that you can only specify one service in a Trust Policy.
It looks like you have an indentation issue. The second item in the array needs to be indented.

API Gateway does not have permission to assume the provided role DynamoDB

I'm trying to follow this tutorial, but when I try to test the API I've created, I get the following message:
API Gateway does not have permission to assume the provided role
The API request should be posting to a DynamoDB table I've created.
I've created an IAM Role and attached the policy AmazonDynamoDBFullAccess. I've also tried attaching this policy to my administrator user.
Here is the integration request in my API:
Any help is much appreciated.
Below worked for me
Go to IAM > Roles > whateverRole > Trust Relationships > Edit Trust Relationship and add apigateway under Statements
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
},
{
"Effect": "Allow",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Assisted by this guy https://histerr.blogspot.com/2016/06/api-gateway-does-not-have-permission-to.html?showComment=1549214559316#c3046645274286738526
The ARN you have provided for the IAM Role is a policy. It needs to be a role. Please go to your generated role and update your ARN to that. It should look something like this *:role/AmazonDynamoDBFullAccess-201709151726