AWS KMS密钥策略隐式允许跨账户访问的原因与限制方案咨询
问题1解答
- 你观察到的现象符合AWS IAM的权限规则:当你在KMS密钥策略中指定
Principal为服务主体sns.amazonaws.com时,授权对象是全局的SNS服务实体,而非绑定到单一AWS账户的SNS资源。跨账户请求的隐式拒绝规则仅适用于AWS账户、IAM用户/角色这类账户级主体,对服务主体不生效。 - 你当前的配置确实会导致该KMS密钥对所有AWS账户的SNS服务公开:只要其他AWS账户的SNS主题能通过你SQS队列的资源策略校验,就可以调用该KMS密钥完成消息投递的加密操作,不需要额外在KMS策略中配置对方账户的权限。
- 链路运行的逻辑是:账户B的SNS向你的SQS投递消息时,由SNS服务本身以服务身份请求调用你账户A的KMS密钥,请求身份是
sns.amazonaws.com,符合你KMS策略的授权规则,因此可以正常通过校验。
问题2解答
尽管aws:SourceArn、aws:SourceAccount条件键不适用于KMS策略的服务主体场景,但可以通过以下两种方案实现权限限制:
方案1:使用KMS专属条件键缩小授权范围(推荐,改造成本最低)
在KMS密钥策略的SNS服务授权语句中添加kms:CallerAccount和kms:ViaService条件键,严格限制仅指定区域、指定账户的SNS服务可以调用密钥,同时收紧不必要的KMS权限,示例配置如下:
{ "Effect": "Allow", "Principal": {"Service": "sns.amazonaws.com"}, "Action": ["kms:GenerateDataKey", "kms:Decrypt"], "Resource": "*", "Condition": { "StringEquals": { "kms:CallerAccount": "[替换为账户B的12位AWS账户ID]", "kms:ViaService": "sns.[替换为SNS主题所在的区域,例如us-east-1].amazonaws.com" } } }
kms:CallerAccount会校验发起KMS请求的服务所属的AWS账户ID,kms:ViaService会校验请求发起的服务端点,二者组合可以完全实现指定账户SNS服务的访问限制。
方案2:调整加密链路配置
你可以要求账户B的SNS主题启用自身的KMS加密,使用账户B托管的密钥完成SNS侧的消息加密,SNS向你的SQS投递消息时,会先使用账户B的KMS解密消息,再使用你SQS的KMS密钥完成入队加密,该场景下你不需要在KMS策略中给SNS服务任何权限,仅保留SQS服务的必要授权即可。
额外优化建议:你当前KMS策略给SNS、SQS服务授予了
kms:*的全权限,存在过度授权风险,建议将服务所需权限收敛到仅kms:GenerateDataKey、kms:Decrypt两个必要动作即可。
内容的提问来源于stack exchange,提问作者Marco K
相关产品推荐
相关产品推荐

