diff --git a/backend/googlecloudstorage/googlecloudstorage.go b/backend/googlecloudstorage/googlecloudstorage.go index 65f010dab..e72ab148a 100644 --- a/backend/googlecloudstorage/googlecloudstorage.go +++ b/backend/googlecloudstorage/googlecloudstorage.go @@ -147,6 +147,22 @@ func init() { Value: "publicReadWrite", Help: "Project team owners get OWNER access, and all Users get WRITER access.", }}, + }, { + Name: "bucket_policy_only", + Help: `Access checks should use bucket-level IAM policies. + +If you want to upload objects to a bucket with Bucket Policy Only set +then you will need to set this. + +When it is set, rclone: + +- ignores ACLs set on buckets +- ignores ACLs set on objects +- creates buckets with Bucket Policy Only set + +Docs: https://cloud.google.com/storage/docs/bucket-policy-only +`, + Default: false, }, { Name: "location", Help: "Location for the newly created buckets.", @@ -244,6 +260,7 @@ type Options struct { ServiceAccountCredentials string `config:"service_account_credentials"` ObjectACL string `config:"object_acl"` BucketACL string `config:"bucket_acl"` + BucketPolicyOnly bool `config:"bucket_policy_only"` Location string `config:"location"` StorageClass string `config:"storage_class"` } @@ -716,8 +733,19 @@ func (f *Fs) Mkdir(dir string) (err error) { Location: f.opt.Location, StorageClass: f.opt.StorageClass, } + if f.opt.BucketPolicyOnly { + bucket.IamConfiguration = &storage.BucketIamConfiguration{ + BucketPolicyOnly: &storage.BucketIamConfigurationBucketPolicyOnly{ + Enabled: true, + }, + } + } err = f.pacer.Call(func() (bool, error) { - _, err = f.svc.Buckets.Insert(f.opt.ProjectNumber, &bucket).PredefinedAcl(f.opt.BucketACL).Do() + insertBucket := f.svc.Buckets.Insert(f.opt.ProjectNumber, &bucket) + if !f.opt.BucketPolicyOnly { + insertBucket.PredefinedAcl(f.opt.BucketACL) + } + _, err = insertBucket.Do() return shouldRetry(err) }) if err == nil { @@ -983,7 +1011,11 @@ func (o *Object) Update(in io.Reader, src fs.ObjectInfo, options ...fs.OpenOptio } var newObject *storage.Object err = o.fs.pacer.CallNoRetry(func() (bool, error) { - newObject, err = o.fs.svc.Objects.Insert(o.fs.bucket, &object).Media(in, googleapi.ContentType("")).Name(object.Name).PredefinedAcl(o.fs.opt.ObjectACL).Do() + insertObject := o.fs.svc.Objects.Insert(o.fs.bucket, &object).Media(in, googleapi.ContentType("")).Name(object.Name) + if !o.fs.opt.BucketPolicyOnly { + insertObject.PredefinedAcl(o.fs.opt.ObjectACL) + } + newObject, err = insertObject.Do() return shouldRetry(err) }) if err != nil { diff --git a/docs/content/googlecloudstorage.md b/docs/content/googlecloudstorage.md index 86843bf65..8d9f136cb 100644 --- a/docs/content/googlecloudstorage.md +++ b/docs/content/googlecloudstorage.md @@ -342,6 +342,27 @@ Access Control List for new buckets. - "publicReadWrite" - Project team owners get OWNER access, and all Users get WRITER access. +#### --gcs-bucket-policy-only + +Access checks should use bucket-level IAM policies. + +If you want to upload objects to a bucket with Bucket Policy Only set +then you will need to set this. + +When it is set, rclone: + +- ignores ACLs set on buckets +- ignores ACLs set on objects +- creates buckets with Bucket Policy Only set + +Docs: https://cloud.google.com/storage/docs/bucket-policy-only + + +- Config: bucket_policy_only +- Env Var: RCLONE_GCS_BUCKET_POLICY_ONLY +- Type: bool +- Default: false + #### --gcs-location Location for the newly created buckets.