为何CodeStar Notifications无法向默认AWS托管密钥加密的SNS Topic发送通知?
我正尝试通过CodeStar Notifications将CodePipeline通知发送至SNS Topic。该SNS Topic采用AWS托管密钥(而非客户托管密钥)加密,且其访问策略已允许CodeStar发送通知。
该SNS密钥(默认别名alias/aws/sns)的默认策略如下:
{ "Version": "2012-10-17", "Id": "auto-sns-1", "Statement": [ { "Sid": "Allow access through SNS for all principals in the account that are authorized to use SNS", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": [ "kms:Decrypt", "kms:GenerateDataKey*", "kms:CreateGrant", "kms:ListGrants", "kms:DescribeKey" ], "Resource": "*", "Condition": { "StringEquals": { "kms:CallerAccount": "xxxxxxxx", "kms:ViaService": "sns.xxxx.amazonaws.com" } } }, { "Sid": "Allow direct access to key metadata to the account", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::xxxxxx:root" }, "Action": [ "kms:Describe*", "kms:Get*", "kms:List*", "kms:RevokeGrant" ], "Resource": "*" } ] }
其他AWS实体(如手动审批通知的IAM角色)可正常向该Topic发送通知,移除加密后CodeStar也能正常发送。我查阅了AWS文档,其中提到加密SNS的策略默认Principal设为所有AWS身份,理论上应允许CodeStar处理加解密操作。
请问是否存在CodeStar无法向默认AWS托管密钥加密的SNS Topic发送通知的限制?
是的,这里存在一个容易被忽略的机制限制:CodeStar Notifications在发送加密消息时,不会通过SNS服务的路径触发KMS权限校验,而是直接调用KMS密钥进行加解密操作,这就导致默认AWS托管SNS密钥策略中的kms:ViaService条件无法匹配,从而被拒绝访问。
默认的alias/aws/sns密钥策略第一条语句,通过kms:ViaService: sns.xxxx.amazonaws.com限制了只有通过SNS服务发起的请求才能使用该密钥。但CodeStar Notifications的工作逻辑是:服务先自行调用KMS生成数据密钥,加密消息后再发送给SNS,而非让SNS去调用KMS处理加密。这使得请求的ViaService字段是CodeStar Notifications的服务域名(如codestar-notifications.xxxx.amazonaws.com),无法满足默认策略的条件。
解决方法是修改AWS托管SNS密钥的策略,添加一条允许CodeStar Notifications直接访问密钥的语句:
{ "Sid": "Allow CodeStar Notifications to access KMS key", "Effect": "Allow", "Principal": { "Service": "codestar-notifications.amazonaws.com" }, "Action": [ "kms:Decrypt", "kms:GenerateDataKey*" ], "Resource": "*", "Condition": { "StringEquals": { "kms:CallerAccount": "xxxxxxxx" } } }
添加该语句后,CodeStar Notifications就能直接获取KMS密钥的权限来处理加密消息,从而正常向加密的SNS Topic发送通知。
另外需要确认:你的SNS Topic访问策略已正确允许CodeStar Notifications服务(codestar-notifications.amazonaws.com)作为主体发布消息,这一步你已经完成,因此仅需调整KMS密钥策略即可。
内容的提问来源于stack exchange,提问作者Jatin Mehrotra

