使用Lambda函数删除S3对象时遭遇Access Denied错误求助
S3 DeleteObjectCommand 报 Access Denied 但 Put/Get 正常的排查方案
可能的原因及解决步骤
1. 检查桶是否开启版本控制
如果S3桶开启了版本控制,直接调用DeleteObjectCommand只会添加删除标记(Delete Marker),若权限策略限制了删除标记的创建,或你需要删除特定版本的对象,就会触发报错。
- 解决方式:
- 若要彻底删除对象,调用
DeleteObjectCommand时需指定VersionId参数:const command = new DeleteObjectCommand({ Bucket: 'somethingsold-uploads', Key: key, VersionId: '目标对象的版本ID' // 可通过ListObjectVersions接口获取 }) - 若不需要版本控制,可直接关闭桶的版本控制功能。
- 若要彻底删除对象,调用
2. 检查对象是否启用Object Lock
如果对象开启了WORM(Write Once Read Many)锁,且处于不可删除的保留周期内,会直接返回Access Denied。
- 解决方式:
- 进入S3控制台查看目标对象的Object Lock状态,确认是否处于锁定周期。
- 若为合法锁定需求,需等待锁过期后再删除;若为误配置,可调整锁策略。
3. 修复Lambda凭证冲突问题
你的代码中硬编码了IAM用户凭证,但Lambda本身已附加IAM角色,这会导致权限优先级冲突——Lambda执行时会优先使用代码内的凭证,而非角色权限。
- 解决方式:
- 删除代码中的
credentials配置,让Lambda自动使用附加的IAM角色:const s3Client = new S3Client({ region: 'us-east-1' // 移除credentials字段 }); - 确保Lambda角色的信任策略允许Lambda服务扮演该角色:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
- 删除代码中的
4. 排查隐式拒绝策略
虽然你的桶策略允许指定主体执行s3:*操作,但如果存在组织级SCP、账户级权限边界等优先级更高的拒绝策略,会覆盖允许规则。
- 解决方式:
- 使用AWS IAM Access Analyzer检查权限配置,确认是否存在隐藏的拒绝语句。
- 检查AWS Organizations的SCP策略,是否限制了S3删除操作。
5. 验证Key参数的编码一致性
如果Key包含特殊字符(空格、中文、URL编码字符),可能导致请求路径与实际存储的对象路径不匹配,触发权限错误(S3对Key的大小写、编码敏感)。
- 解决方式:
- 打印并验证
event.queryStringParameters.key的原始值,确保与S3对象的Key完全一致。 - 若前端传递的是URL编码后的字符串,需先解码:
const key = decodeURIComponent(event.queryStringParameters.key);
- 打印并验证
额外验证手段
- 使用AWS CLI测试删除操作,排查是否为代码逻辑问题:
aws s3 rm s3://somethingsold-uploads/你的对象Key - 启用S3服务器访问日志,查看请求的身份、资源、错误详情,定位具体拒绝原因。
内容的提问来源于stack exchange,提问作者Andy Vu
相关产品推荐
相关产品推荐

