Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS Cloudwatch can not publish to SNS Topic with SSE

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.

like image 395
Breedly Avatar asked May 31 '19 15:05

Breedly


1 Answers

Just summarizing the correct answer here because the accepted answer seems to be outdated:.

  1. 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.

  2. 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": "*"
        }
    ]
}
like image 55
grappler Avatar answered Nov 08 '22 00:11

grappler