跨账号调用S3时遇403访问拒绝问题求助(CloudFormation部署)
一、逐步排查权限链路
验证R1的信任策略:确保信任策略的
Principal是Worker账号的正确ID,而非别名或错误ARN。CloudFormation示例配置:AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: AWS: arn:aws:iam::WORKER_ACCOUNT_ID:root Action: sts:AssumeRole多Worker账号场景需添加所有目标账号ID,生产环境避免用通配符。
检查R2的AssumeRole权限:确认R2的策略明确允许对R1的完整ARN执行
sts:AssumeRole,CloudFormation示例:PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: sts:AssumeRole Resource: arn:aws:iam::DATA_ACCOUNT_ID:role/R1重点核对Resource字段中的账号ID和角色名是否准确。
校验S3桶策略有效性:即使R1附带S3 Full Access,桶策略也可能存在冲突。确保桶策略明确允许R1执行
s3:PutObject,且Resource包含桶内对象路径(/*):BucketPolicy: PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: AWS: arn:aws:iam::DATA_ACCOUNT_ID:role/R1 Action: s3:PutObject Resource: arn:aws:s3:::YOUR_BUCKET_NAME/*确认Lambda代码的角色切换逻辑:Lambda必须显式调用
sts:AssumeRole获取R1的临时凭证,再用该凭证操作S3。直接使用R2凭证访问桶会触发403,Python示例代码:import boto3 def lambda_handler(event, context): sts_client = boto3.client('sts') assumed_role = sts_client.assume_role( RoleArn='arn:aws:iam::DATA_ACCOUNT_ID:role/R1', RoleSessionName='LambdaAssumeRoleSession' ) s3_client = boto3.client( 's3', aws_access_key_id=assumed_role['Credentials']['AccessKeyId'], aws_secret_access_key=assumed_role['Credentials']['SecretAccessKey'], aws_session_token=assumed_role['Credentials']['SessionToken'] ) s3_client.put_object( Bucket='YOUR_BUCKET_NAME', Key='test.txt', Body=b'Test content' )
二、模拟角色行为的简便方法
用CLI模拟R2切换R1:获取R2的临时凭证(可从IAM角色页面生成),执行以下命令验证AssumeRole是否成功:
aws sts assume-role --role-arn arn:aws:iam::DATA_ACCOUNT_ID:role/R1 --role-session-name test-session返回临时凭证则说明R2权限和R1信任策略正常,报错则根据提示定位问题。
用临时凭证测试S3上传:将上述命令返回的临时凭证设为环境变量,执行上传测试:
export AWS_ACCESS_KEY_ID=临时AccessKeyId export AWS_SECRET_ACCESS_KEY=临时SecretAccessKey export AWS_SESSION_TOKEN=临时SessionToken aws s3 cp test.txt s3://YOUR_BUCKET_NAME/test.txt成功则说明R1的S3权限和桶策略无问题,失败则聚焦桶策略或R1权限排查。
查看CloudTrail日志:在Data和Worker账号开启CloudTrail,搜索
AssumeRole和PutObject事件,日志会提供具体错误原因(如桶策略拦截、IAM权限不足),比Lambda的模糊报错更精准。
三、CloudFormation部署常见坑点
- 资源依赖关系:确保R1角色在桶策略创建前已存在,通过
DependsOn明确依赖:MyBucketPolicy: Type: AWS::S3::BucketPolicy DependsOn: R1Role Properties: Bucket: !Ref MyBucket PolicyDocument: ... - ARN拼写错误:用CloudFormation参数传递账号ID,避免硬编码错误:
Parameters: DataAccountId: Type: String WorkerAccountIds: Type: CommaDelimitedList - 权限边界限制:若R2配置了权限边界,需确保边界允许
sts:AssumeRole操作,否则附加策略会被覆盖。
内容的提问来源于stack exchange,提问作者Jeremy Fisher

