I have a KMS policy statement like given below.
{
"Sid": "Allow use of the key by SNS",
"Effect": "Allow",
"Principal": {
"Service": "sns.amazonaws.com"
},
"Action": [
"kms:DescribeKey",
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*"
],
"Resource": "*"
}
Will this make SNS (Or, any service I mention as Principal) from any AWS account to access my KMS key? I couldn't find any clear documentation around it.
By allowing a service principal to perform some actions over a KMS key, you are not allowing directly access to AWS accounts, but to the internal AWS service principal (which does not belong to an specific AWS account).
For instance, if you have a CloudWatch alarm publishing to an SNS encrypted topic, you will need to include into the KMS resource policy, an statement like:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Service": "cloudwatch.amazonaws.com"
},
"Action": [
"kms:GenerateDataKey",
"kms:Decrypt"
],
"Resource": "*"
}]
}
However, by doing this you are technically giving potential access to your KMS key from another accounts, if that other accounts, for instance, configure a CloudWatch alarm to publish into your SNS topic (assuming the SNS topic also allows publishing messages from cloudwatch.amazonaws.com service principal).
Thats why it is strongly recommended to add conditions keys when defining a key policy, in order to allow access only from specific caller accounts or even specific AWS resource ARN's, and to avoid a potential confused deputy scenario:
When the principal in a key policy statement is an AWS service principal, we strongly recommend that you use the aws:SourceArn or aws:SourceAccount global condition keys, in addition to the kms:EncryptionContext:context-key condition key.
Quote from Permissions for AWS services in key policies.