From cc9df7c34ce565f624d7a5c3a40eeeb6c591c06d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Serdar=20=C3=96zer?= Date: Thu, 12 Feb 2026 15:35:01 +0100 Subject: [PATCH 1/2] feat: uniform access level added to bucket creation - If flag is enabled, it will create the bucket with uniform access level. - this was requirement from ccng side. --- gcs/client/client.go | 4 ++++ gcs/config/config.go | 5 +++++ gcs/config/config_test.go | 23 +++++++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/gcs/client/client.go b/gcs/client/client.go index ce942b3..ede0af2 100644 --- a/gcs/client/client.go +++ b/gcs/client/client.go @@ -433,6 +433,10 @@ func (client *GCSBlobstore) EnsureStorageExists() error { battr.StorageClass = client.config.StorageClass } + if client.config.UniformBucketLevelAccess { + battr.UniformBucketLevelAccess = storage.UniformBucketLevelAccess{Enabled: true} + } + projectID, err := extractProjectID(ctx, client.config) if err != nil { return fmt.Errorf("extracting project ID: %w", err) diff --git a/gcs/config/config.go b/gcs/config/config.go index 29ee733..28dcf09 100644 --- a/gcs/config/config.go +++ b/gcs/config/config.go @@ -39,6 +39,11 @@ type GCSCli struct { // StorageClass is the type of storage used for objects added to the bucket // https://cloud.google.com/storage/docs/storage-classes StorageClass string `json:"storage_class"` + // UniformBucketLevelAccess enables uniform bucket-level access control. + // When true, disables ACLs and uses only IAM for permissions. + // When false (default), buckets use fine-grained ACL-based access control. + // https://cloud.google.com/storage/docs/uniform-bucket-level-access + UniformBucketLevelAccess bool `json:"uniform_bucket_level_access"` // EncryptionKey is a Customer-Supplied encryption key used to // encrypt objects added to the bucket. // If left empty, no explicit encryption key will be used; diff --git a/gcs/config/config_test.go b/gcs/config/config_test.go index 2d856c8..5031fd3 100644 --- a/gcs/config/config_test.go +++ b/gcs/config/config_test.go @@ -146,4 +146,27 @@ var _ = Describe("BlobstoreClient configuration", func() { }) }) + Describe("when uniform_bucket_level_access is set to true", func() { + dummyJSONBytes := []byte(`{"bucket_name": "some-bucket", "uniform_bucket_level_access":true}`) + dummyJSONReader := bytes.NewReader(dummyJSONBytes) + + It("it has value true", func() { + c, err := NewFromReader(dummyJSONReader) + Expect(err).To(BeNil()) + Expect(c.UniformBucketLevelAccess).To(BeTrue()) + + }) + }) + + Describe("when uniform_bucket_level_access is not set", func() { + dummyJSONBytes := []byte(`{"bucket_name": "some-bucket"}`) + dummyJSONReader := bytes.NewReader(dummyJSONBytes) + + It("it has value false", func() { + c, err := NewFromReader(dummyJSONReader) + Expect(err).To(BeNil()) + Expect(c.UniformBucketLevelAccess).To(BeFalse()) + }) + }) + }) From 25b6b4da2cf6821f1a8ed6e99813a3b543c4e136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Serdar=20=C3=96zer?= Date: Thu, 12 Feb 2026 15:54:45 +0100 Subject: [PATCH 2/2] doc: reamed updated with new config parameter uniform_bucket_level_access --- gcs/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gcs/README.md b/gcs/README.md index 6a6b59e..7917f94 100644 --- a/gcs/README.md +++ b/gcs/README.md @@ -18,6 +18,7 @@ The GCS client requires a JSON configuration file. "json_key": " (required if credentials_source = 'static')", "storage_class": " (optional - default: 'STANDARD', check for more options=https://docs.cloud.google.com/storage/docs/storage-classes)", "encryption_key": " (optional)", + "uniform_bucket_level_access": " (optional)" } ``` @@ -26,6 +27,12 @@ The GCS client requires a JSON configuration file. * **"none":** specifies that credentials are explicitly empty and that the client should be restricted to a read-only scope. * **"static:"** specifies that a service account file included in json_key should be used for authentication. +### Bucket Creation +The `ensure-storage-exists` command creates a bucket if it does not already exist. The `uniform_bucket_level_access` configuration option controls the access control model: +* **`true`**: Creates a bucket with uniform bucket-level access (IAM-only, ACLs disabled) +* **`false` or omitted (default)**: Creates a bucket with fine-grained access control (ACLs enabled) + + ### Authentication Methods (`credentials_source`) * `static`: A [service account](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) key will be provided via the `json_key` field. * `none`: No credentials are provided. The client is reading from a public bucket.