跨账号调用SQS SendMessage遇Access Denied问题求助
跨账号Lambda调用SQS SendMessage遇403 Access Denied排查
问题背景
账号A的Go语言Lambda函数调用账号B的SQS队列sqs:SendMessage接口时触发403 Access Denied错误,已完成以下排查:
- Lambda关联的IAM角色已配置内联策略,明确允许对目标队列执行
sqs:SendMessage操作,且通过Lambda控制台「配置-权限-资源摘要」确认权限生效 - 账号B的目标队列已开放权限策略,允许账号A内所有用户/角色调用SendMessage,未启用KMS加密,且已放宽权限范围用于测试
- 通过环境变量从Terraform获取队列URL,已确认URL正确;日志显示
sqs.SendMessageInput结构体中的QueueUrl为完整地址,但SDK返回的错误信息中URL仅显示https://sqs.us-west-2.amazonaws.com/
SDK错误信息
AccessDenied: Access to the resource https://sqs.us-west-2.amazonaws.com/ is denied. status code: 403, request id: 27725068-xxxx-xxxx-xxxx-0cbc781c2526
SendMessageInput日志片段
{ "DelaySeconds": null, "MessageAttributes": null, "MessageBody": "{\"CreatedTime\":1683599412006493,\"FooID\":\"1bec4d4a-336d-4a7c-bb0e-e73b6eb23c55\",\"S3Bucket\":\"myredactedbucketname\",\"S3Key\":\"b9f01b2f-4043-4e6b-b9e8-f47ea630a053/b992fee7-0181-4a0f-8cc3-e29c54747135\"}", "MessageDeduplicationId": null, "MessageGroupId": null, "MessageSystemAttributes": null, "QueueUrl": "https://sqs.us-west-2.amazonaws.com/<my-aws-account-id>/asset_xxxxxxx_queue_us-west-2" }
可能的原因
- IAM策略资源匹配错误:检查Lambda角色内联策略中的SQS队列ARN是否完全正确,ARN格式应为
arn:aws:sqs:us-west-2:<账号B ID>:asset_xxxxxxx_queue_us-west-2,若策略中使用了错误的通配符或拼写错误,会导致权限不匹配 - 跨账号权限的Principal配置错误:账号B的队列权限策略中,
Principal是否正确指定了账号A的ID或Lambda角色ARN?比如配置为{"AWS": "arn:aws:iam::<账号A ID>:root"},若账号ID或角色ARN写错,会直接触发权限拒绝 - Lambda VPC限制:如果Lambda部署在VPC内,需确认VPC安全组和网络ACL允许出站访问SQS服务(443端口);若使用VPC端点,需检查SQS端点的策略是否允许访问账号B的队列
- AWS区域不匹配:确认Lambda所在区域与SQS队列区域均为us-west-2,若Go SDK客户端初始化时指定了错误区域,会导致请求发送到错误区域的SQS服务,触发权限拒绝
- IAM角色权限边界限制:如果Lambda的IAM角色设置了权限边界,即使内联策略允许操作,权限边界也可能限制跨账号
sqs:SendMessage的权限,需检查权限边界是否包含对应权限 - 临时凭证异常:Lambda使用的临时IAM凭证可能存在权限限制,可在Lambda中打印凭证所属角色信息(注意不泄露敏感数据),确认凭证是否对应正确的IAM角色
获取更详细错误信息的方法
- 启用CloudTrail日志:在账号A和账号B分别开启CloudTrail,查看
SendMessageAPI调用的详细日志,其中会记录调用者ARN、资源ARN、错误代码的具体触发原因 - 使用IAM Access Analyzer:在账号A中运行IAM Access Analyzer,检查Lambda角色的权限是否能有效访问账号B的SQS队列;在账号B中运行Access Analyzer,检查队列权限策略是否允许账号A的角色访问
- 开启SDK调试日志:在Go代码中启用AWS SDK的调试日志,查看完整的请求和响应内容,示例代码如下:
import "github.com/aws/aws-sdk-go-v2/aws" import "github.com/aws/aws-sdk-go-v2/config" cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion("us-west-2"), config.WithClientLogMode(aws.LogRequestWithBody|aws.LogResponseWithBody), )
- 本地命令行测试:通过
aws sts assume-role获取账号A Lambda角色的临时凭证,本地执行aws sqs send-message命令测试,添加--debug参数查看完整请求过程
内容的提问来源于stack exchange,提问作者Nevo
相关产品推荐
相关产品推荐

