使用默认aws/s3 KMS密钥加密的S3对象跨账户访问问题咨询
跨账户访问AWS托管KMS加密S3存储桶解决方案
核心问题说明
AWS托管密钥aws/s3的密钥策略由AWS官方维护,用户无法自定义修改,其默认规则仅支持密钥所属账户(即你提到的账户A)的IAM实体调用对应KMS解密操作,你当前的配置遗漏了跨账户角色扮演的必要权限项,所以返回访问拒绝。
分步修复操作
- 修正账户A跨账户角色的信任策略
你当前创建的账户A角色需要明确信任账户B的Lambda执行角色,而非仅信任账户B根主体,示例信任策略配置如下:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<账户B的12位ID>:role/<账户B的Lambda执行角色名称>" }, "Action": "sts:AssumeRole" } ] } - 给账户B的Lambda执行角色添加角色扮演权限
账户B的Lambda执行角色默认没有扮演其他账户角色的权限,需要在其权限策略中添加以下语句:{ "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::<账户A的12位ID>:role/<你在账户A创建的跨账户角色名称>" } - 调整Lambda调用逻辑
Lambda代码中需要先调用STS接口获取账户A角色的临时凭证,再用该临时凭证调用S3的GetObject接口,示例Python代码如下:import boto3 # 调用STS扮演账户A的角色 sts_client = boto3.client('sts') assumed_role_resp = sts_client.assume_role( RoleArn="arn:aws:iam::<账户A的12位ID>:role/<账户A的跨账户角色名>", RoleSessionName="s3-cross-account-session" ) creds = assumed_role_resp['Credentials'] # 用账户A的临时凭证初始化S3客户端 s3_client = boto3.client( 's3', aws_access_key_id=creds['AccessKeyId'], aws_secret_access_key=creds['SecretAccessKey'], aws_session_token=creds['SessionToken'] ) # 调用GetObject读取对象,无需额外加密参数 obj_resp = s3_client.get_object(Bucket="my-s3", Key="<你的对象路径>") - 可选优化方案
由于aws/s3托管密钥的跨账户使用限制较多,建议你将S3桶的默认加密方式替换为账户A的客户管理CMK,你可以自主修改CMK的密钥策略直接允许账户B的Lambda角色解密,不需要额外配置跨账户角色扮演,稳定性更高。
问题排查方法
如果调整配置后仍报错,可以在账户A的CloudTrail控制台查询对应时间的GetObject和Decrypt事件,明确是S3权限拒绝还是KMS权限拒绝,再针对性调整配置。
内容的提问来源于stack exchange,提问作者AWS_Lernar
相关产品推荐
相关产品推荐

