为什么 gsutil cp 在版本化存储桶上需要 storage.objects.delete?

Why does gsutil cp require storage.objects.delete on versioned bucket?

我正在使用服务帐户将文件上传到 Google 具有版本控制的 Cloud Storage 存储桶。我想将服务帐户权限保持在最低限度,它只需要上传文件,所以我不想授予它删除文件的权限,但上传失败(仅在流式传输所有内容后!)说它需要删除权限。

不应该是创建新版本而不是删除吗?

命令如下:

cmd-that-streams | gsutil cp -v - gs://my-bucket/${FILE}
ResumableUploadAbortException: 403 service-account@project.iam.gserviceaccount.com does not have storage.objects.delete access to my-bucket/file

我仔细检查了存储桶上是否启用了版本控制

> gsutil versioning get gs://my-bucket
gs://my-bucket: Enabled

如果您按照 cloud storage gsutil commands.

执行 gsutl cp 命令,则需要权限 storage.objects.delete

Command: cp

Required permissions:

  • storage.objects.list* (for the destination bucket)
  • storage.objects.get (for the source objects)
  • storage.objects.create (for the destination bucket)
  • storage.objects.delete** (for the destination bucket)

**This permission is only required if you don't use the -n flag and you insert an object that has the same name as an object that already exists in the bucket.

Google 文档建议使用 -n(不要覆盖现有文件),因此不需要 storage.objects.delete。但是您的用例使用版本控制,您将需要覆盖,因此您将 需要添加 storage.objects.delete 您的权限。

我在启用了存储桶版本控制的情况下对此进行了测试,但只有 1 个版本。具有角色 Storage Object Creator and Storage Object Viewer.

的服务帐户

查看命令和输出的屏幕截图:

如果您要覆盖一个对象,无论其父存储桶是否启用了版本控制,您都必须对该对象具有 storage.objects.delete 权限。

版本控制的工作原理是,当您删除对象的“实时”版本时,该版本将被标记为“非当前”版本(并且 the timeDeleted field 已填充)。为了在活动版本已经存在时创建对象的新版本(即覆盖对象),发生的事务是:

  • 删除当前版本
  • 创建成为“实时”或“当前”版本的新版本