问题
I'm using a service account to upload a file to Google Cloud Storage bucket that has versioning. I want to keep the service account privileges minimal, it only ever needs to upload files so I don't want to give it permission to delete files, but the upload fails (only after streaming everything!) saying it requires delete permission.
Shouldn't it be creating a new version instead of deleting?
Here's the command:
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
I've double checked that versioning is enabled on the bucket
> gsutil versioning get gs://my-bucket
gs://my-bucket: Enabled
回答1:
The permission storage.objects.delete
is required if you are executing the gsutl cp
command as per cloud storage gsutil commands.
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 docs suggests to use -n (do not overwrite an existing file) so storage.objects.delete
won't be required. But your use case uses versioning and you will be needing to overwrite, thus you will need to add storage.objects.delete
on your permissions.
I tested this with a bucket versioning is enabled and only has 1 version. Service account that have roles Storage Object Creator and Storage Object Viewer.
See screenshot for the commands and output:
回答2:
If you're overwriting an object, regardless of whether or not its parent bucket has versioning enabled, you must have storage.objects.delete
permission for that object.
Versioning works such that when you delete the "live" version of an object, that version is marked as a "noncurrent" version (and the timeDeleted field is populated). In order to create a new version of an object when a live version already exists (i.e. overwriting the object), the transaction that happens is:
- Delete the current version
- Create a new version that becomes the "live" or "current" version
来源:https://stackoverflow.com/questions/66129154/why-does-gsutil-cp-require-storage-objects-delete-on-versioned-bucket