使用roles/storage.objectCreator角色上传GCS文件遇权限问题求助
我尝试为某服务账号授予有限权限,使其能在指定Google Cloud Storage(GCS)存储桶中创建文件。为避免创建自定义角色,我选择在存储桶上为该账号配置预定义角色roles/storage.objectCreator。
随后,我通过impersonate该服务账号执行以下Python代码:
storage_client = storage.Client("project") bucket_name = "bucket" bucket = storage_client.get_bucket(bucket_name) blob = bucket.blob("test.txt") blob.upload_from_string("Hello World")
但执行时收到权限拒绝错误:
sa-name@project.iam.gserviceaccount.com does not have storage.buckets.get access to the Google Cloud Storage bucket. Permission 'storage.buckets.get' denied on resource (or it may not exist)
我原本以为此配置已足够,但实际并非如此。我知晓可创建自定义角色来定义所需权限集,但能否在仅保留roles/storage.objectCreator角色权限范围的前提下完成文件上传?或许可通过修改Python代码,避免实例化存储桶对象来实现?
问题原因
get_bucket()方法会触发GCS的Buckets:Get API调用,该操作需要storage.buckets.get权限,但roles/storage.objectCreator预定义角色并不包含此权限,因此导致权限拒绝错误。
解决方案:修改代码跳过Bucket元数据请求
可以直接构造Blob对象,避免调用需要获取Bucket元数据的get_bucket()方法。以下是修改后的代码:
from google.cloud import storage storage_client = storage.Client("project") # 直接通过客户端构造Bucket引用(本地对象,不触发API请求),再创建Blob blob = storage_client.bucket("bucket").blob("test.txt") blob.upload_from_string("Hello World")
或者更明确的写法:
from google.cloud import storage storage_client = storage.Client("project") bucket_name = "bucket" # 仅创建本地Bucket对象引用,不发起API请求 bucket_ref = storage_client.bucket(bucket_name) blob = storage.Blob("test.txt", bucket_ref) blob.upload_from_string("Hello World")
这里的核心是:storage_client.bucket(bucket_name)只是在本地创建一个Bucket的引用对象,不会向GCS服务器发起获取Bucket元数据的请求,因此不需要storage.buckets.get权限。而roles/storage.objectCreator包含的storage.objects.create权限足以完成文件上传操作。
内容的提问来源于stack exchange,提问作者Luiscri

