Google Cloud Storage存储桶IAM条件配置问题:含resource.type条件的服务账号无法上传文件
问题原因分析与解决方案
这个问题我之前帮人排查过,核心原因其实是你误解了IAM条件里resource.type对应的资源类型,并不是冗余配置的问题,而是条件和你执行的操作不匹配导致的权限被拒绝。
关键问题点拆解
- 当你执行
storage.objects.create(上传文件)操作时,你操作的目标资源是存储对象,对应的resource.type是storage.googleapis.com/Object,而不是你条件里写的storage.googleapis.com/Bucket。 - 你的IAM条件限定了只有操作Bucket类型的资源时才生效,这就导致创建对象的请求完全不匹配这个条件,服务账号自然拿不到对应的权限,触发403错误。
为什么去掉resource.type就正常?
当你只保留resource.name.startsWith("projects/_/buckets/stagestorage")时,这个条件会匹配桶和桶下所有对象的资源名:
- 桶的资源名格式是
projects/_/buckets/stagestorage - 对象的资源名格式是
projects/_/buckets/stagestorage/objects/[你的文件路径]
所以前缀匹配会覆盖这两种资源类型,此时IAM政策对上传对象的操作生效,权限就正常了。
正确的条件写法(如果需要限定资源类型)
如果你确实想同时明确限定桶和对象的操作,可以用逻辑或组合两个条件:
(resource.type == "storage.googleapis.com/Bucket" && resource.name.startsWith("projects/_/buckets/stagestorage")) || (resource.type == "storage.googleapis.com/Object" && resource.name.startsWith("projects/_/buckets/stagestorage/objects/"))
不过其实更简洁的方式是直接保留前缀匹配即可,因为前缀已经足够区分目标桶及其下的所有对象,不需要额外加resource.type。
关于角色的补充说明
你换成Storage Object Admin还是报错,是因为问题根源在IAM条件的资源类型不匹配,和角色本身无关——角色的权限是足够的,但条件把你的请求给过滤掉了。
内容的提问来源于stack exchange,提问作者Dmitry Zimin
相关产品推荐
相关产品推荐

