From c3096a6c0c26ddad8d021c795b5f15f01c7525fc Mon Sep 17 00:00:00 2001 From: mahendra-google Date: Fri, 6 Feb 2026 03:35:28 -0800 Subject: [PATCH 1/8] samples(Storage): Add samples and tests for bucket encryption enforcement configuration (http:/b/465329369) --- ...ucketGetEncryptionEnforcementConfigTest.cs | 50 +++++++++++ ...emoveAllEncryptionEnforcementConfigTest.cs | 48 +++++++++++ ...ucketSetEncryptionEnforcementConfigTest.cs | 62 ++++++++++++++ .../BucketGetEncryptionEnforcementConfig.cs | 60 ++++++++++++++ ...ketRemoveAllEncryptionEnforcementConfig.cs | 51 ++++++++++++ .../BucketSetEncryptionEnforcementConfig.cs | 82 +++++++++++++++++++ 6 files changed, 353 insertions(+) create mode 100644 storage/api/Storage.Samples.Tests/BucketGetEncryptionEnforcementConfigTest.cs create mode 100644 storage/api/Storage.Samples.Tests/BucketRemoveAllEncryptionEnforcementConfigTest.cs create mode 100644 storage/api/Storage.Samples.Tests/BucketSetEncryptionEnforcementConfigTest.cs create mode 100644 storage/api/Storage.Samples/BucketGetEncryptionEnforcementConfig.cs create mode 100644 storage/api/Storage.Samples/BucketRemoveAllEncryptionEnforcementConfig.cs create mode 100644 storage/api/Storage.Samples/BucketSetEncryptionEnforcementConfig.cs diff --git a/storage/api/Storage.Samples.Tests/BucketGetEncryptionEnforcementConfigTest.cs b/storage/api/Storage.Samples.Tests/BucketGetEncryptionEnforcementConfigTest.cs new file mode 100644 index 00000000000..7eb0841510e --- /dev/null +++ b/storage/api/Storage.Samples.Tests/BucketGetEncryptionEnforcementConfigTest.cs @@ -0,0 +1,50 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using Xunit; + +[Collection(nameof(StorageFixture))] +public class BucketGetEncryptionEnforcementConfigTest +{ + private readonly StorageFixture _fixture; + + public BucketGetEncryptionEnforcementConfigTest(StorageFixture fixture) + { + _fixture = fixture; + } + + [Fact] + public void BucketGetEncryptionEnforcementConfig() + { + var bucketSetEncConfigSample = new BucketSetEncryptionEnforcementConfigSample(); + var bucketGetEncConfigSample = new BucketGetEncryptionEnforcementConfigSample(); + var bucketName = _fixture.GenerateBucketName(); + _fixture.CreateBucket(bucketName: bucketName, location: _fixture.KmsKeyLocation); + + string keyName = $"projects/{_fixture.ProjectId}/locations/{_fixture.KmsKeyLocation}/keyRings/{_fixture.KmsKeyRing}/cryptoKeys/{_fixture.KmsKeyName}"; + var bucket = bucketSetEncConfigSample.SetBucketEncryptionEnforcementConfig( + bucketName: bucketName, + kmsKeyName: keyName, + enforceCmek: true); + var bucketEncryptionData = bucketGetEncConfigSample.BucketGetEncryptionEnforcementConfig(bucket.Name); + Assert.NotNull(bucketEncryptionData); + Assert.Equal(keyName, bucketEncryptionData.DefaultKmsKeyName); + Assert.Multiple(() => + { + Assert.Equal("NotRestricted", bucketEncryptionData.CustomerManagedEncryptionEnforcementConfig?.RestrictionMode); + Assert.Equal("FullyRestricted", bucketEncryptionData.CustomerSuppliedEncryptionEnforcementConfig?.RestrictionMode); + Assert.Equal("FullyRestricted", bucketEncryptionData.GoogleManagedEncryptionEnforcementConfig?.RestrictionMode); + }); + } +} diff --git a/storage/api/Storage.Samples.Tests/BucketRemoveAllEncryptionEnforcementConfigTest.cs b/storage/api/Storage.Samples.Tests/BucketRemoveAllEncryptionEnforcementConfigTest.cs new file mode 100644 index 00000000000..c0d47b8dd73 --- /dev/null +++ b/storage/api/Storage.Samples.Tests/BucketRemoveAllEncryptionEnforcementConfigTest.cs @@ -0,0 +1,48 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using Xunit; + +[Collection(nameof(StorageFixture))] +public class BucketRemoveAllEncryptionEnforcementConfigTest +{ + private readonly StorageFixture _fixture; + + public BucketRemoveAllEncryptionEnforcementConfigTest(StorageFixture fixture) + { + _fixture = fixture; + } + + [Fact] + public void BucketRemoveAllEncryptionEnforcementConfig() + { + var bucketSetEncConfigSample = new BucketSetEncryptionEnforcementConfigSample(); + var bucketRemoveEncConfigSample = new BucketRemoveAllEncryptionEnforcementConfigSample(); + var bucketName = _fixture.GenerateBucketName(); + _fixture.CreateBucket(bucketName: bucketName, location: _fixture.KmsKeyLocation); + string keyName = $"projects/{_fixture.ProjectId}/locations/{_fixture.KmsKeyLocation}/keyRings/{_fixture.KmsKeyRing}/cryptoKeys/{_fixture.KmsKeyName}"; + var bucket = bucketSetEncConfigSample.SetBucketEncryptionEnforcementConfig( + bucketName: bucketName, + kmsKeyName: keyName, + enforceCmek: true); + var updatedBucket = bucketRemoveEncConfigSample.BucketRemoveAllEncryptionEnforcementConfig(bucket.Name); + Assert.Equal(updatedBucket.Encryption.DefaultKmsKeyName, bucket.Encryption.DefaultKmsKeyName); + Assert.Multiple(() => + { + Assert.Null(updatedBucket.Encryption.CustomerSuppliedEncryptionEnforcementConfig); + Assert.Null(updatedBucket.Encryption.CustomerManagedEncryptionEnforcementConfig); + Assert.Null(updatedBucket.Encryption.GoogleManagedEncryptionEnforcementConfig); + }); + } +} diff --git a/storage/api/Storage.Samples.Tests/BucketSetEncryptionEnforcementConfigTest.cs b/storage/api/Storage.Samples.Tests/BucketSetEncryptionEnforcementConfigTest.cs new file mode 100644 index 00000000000..9f4d7d4a5d5 --- /dev/null +++ b/storage/api/Storage.Samples.Tests/BucketSetEncryptionEnforcementConfigTest.cs @@ -0,0 +1,62 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using Xunit; + +[Collection(nameof(StorageFixture))] +public class BucketSetEncryptionEnforcementConfigTest +{ + private readonly StorageFixture _fixture; + + public BucketSetEncryptionEnforcementConfigTest(StorageFixture fixture) + { + _fixture = fixture; + } + + [Theory] + [InlineData(true, false, false)] + [InlineData(false, true, false)] + [InlineData(false, false, true)] + public void BucketSetEncryptionEnforcementConfig( + bool enforceCmek, + bool enforceGmek, + bool restrictCsek) + { + var bucketSetEncConfigSample = new BucketSetEncryptionEnforcementConfigSample(); + var bucketName = _fixture.GenerateBucketName(); + string keyName = enforceCmek + ? $"projects/{_fixture.ProjectId}/locations/{_fixture.KmsKeyLocation}/keyRings/{_fixture.KmsKeyRing}/cryptoKeys/{_fixture.KmsKeyName}" + : null; + _fixture.CreateBucket(bucketName: bucketName, location: _fixture.KmsKeyLocation); + var bucket = bucketSetEncConfigSample.SetBucketEncryptionEnforcementConfig( + bucketName: bucketName, + kmsKeyName: keyName, + enforceCmek: enforceCmek, + enforceGmek: enforceGmek, + restrictCsek: restrictCsek); + + string expectedCmek = enforceGmek ? "FullyRestricted" : "NotRestricted"; + string expectedGmek = enforceCmek ? "FullyRestricted" : "NotRestricted"; + string expectedCsek = (enforceCmek || enforceGmek || restrictCsek) ? "FullyRestricted" : "NotRestricted"; + + Assert.Multiple(() => + { + Assert.Equal(expectedCmek, bucket.Encryption.CustomerManagedEncryptionEnforcementConfig?.RestrictionMode); + Assert.Equal(expectedCsek, bucket.Encryption.CustomerSuppliedEncryptionEnforcementConfig?.RestrictionMode); + Assert.Equal(expectedGmek, bucket.Encryption.GoogleManagedEncryptionEnforcementConfig?.RestrictionMode); + + if (enforceCmek) Assert.Equal(keyName, bucket.Encryption.DefaultKmsKeyName); + }); + } +} diff --git a/storage/api/Storage.Samples/BucketGetEncryptionEnforcementConfig.cs b/storage/api/Storage.Samples/BucketGetEncryptionEnforcementConfig.cs new file mode 100644 index 00000000000..062acd829c6 --- /dev/null +++ b/storage/api/Storage.Samples/BucketGetEncryptionEnforcementConfig.cs @@ -0,0 +1,60 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// [START storage_get_encryption_enforcement_config] + +using Google.Apis.Storage.v1.Data; +using Google.Cloud.Storage.V1; +using System; + +public class BucketGetEncryptionEnforcementConfigSample +{ + /// + /// Get the encryption enforcement configuration for the bucket. + /// + /// The name of the bucket. + public Bucket.EncryptionData BucketGetEncryptionEnforcementConfig(string bucketName = "your-unique-bucket-name") + { + var storage = StorageClient.Create(); + var bucket = storage.GetBucket(bucketName); + Console.WriteLine($"Encryption Enforcement Configuration for bucket {bucketName} is as follows:"); + + if (bucket.Encryption == null) + { + Console.WriteLine("No Encryption Configuration is found (Default GMEK is active)"); + return bucket.Encryption; + } + + var gmConfig = bucket.Encryption.GoogleManagedEncryptionEnforcementConfig; + if (gmConfig != null) + { + Console.WriteLine($"Google Managed (GMEK) Enforcement Restriction Mode: {gmConfig.RestrictionMode}"); + Console.WriteLine($"Google Managed (GMEK) Enforcement Effective Time: {gmConfig.EffectiveTimeRaw}"); + } + var cmConfig = bucket.Encryption.CustomerManagedEncryptionEnforcementConfig; + if (cmConfig != null) + { + Console.WriteLine($"Customer Managed (CMEK) Enforcement Restriction Mode: {cmConfig.RestrictionMode}"); + Console.WriteLine($"Customer Managed (CMEK) Enforcement Effective Time: {cmConfig.EffectiveTimeRaw}"); + } + var csConfig = bucket.Encryption.CustomerSuppliedEncryptionEnforcementConfig; + if (csConfig != null) + { + Console.WriteLine($"Customer Supplied (CSEK) Enforcement Restriction Mode: {csConfig.RestrictionMode}"); + Console.WriteLine($"Customer Supplied (CSEK) Enforcement Effective Time: {csConfig.EffectiveTimeRaw}"); + } + return bucket.Encryption; + } +} +// [END storage_get_encryption_enforcement_config] diff --git a/storage/api/Storage.Samples/BucketRemoveAllEncryptionEnforcementConfig.cs b/storage/api/Storage.Samples/BucketRemoveAllEncryptionEnforcementConfig.cs new file mode 100644 index 00000000000..9af55630ba8 --- /dev/null +++ b/storage/api/Storage.Samples/BucketRemoveAllEncryptionEnforcementConfig.cs @@ -0,0 +1,51 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// [START storage_remove_all_encryption_enforcement_config] + +using Google.Apis.Storage.v1.Data; +using Google.Cloud.Storage.V1; +using System; + +public class BucketRemoveAllEncryptionEnforcementConfigSample +{ + /// + /// Remove all encryption enforcement configurations from the bucket. + /// + /// The name of the bucket. + public Bucket BucketRemoveAllEncryptionEnforcementConfig(string bucketName = "your-unique-bucket-name") + { + var storage = StorageClient.Create(); + var bucket = storage.GetBucket(bucketName); + + if (bucket.Encryption is null + || (bucket.Encryption.CustomerManagedEncryptionEnforcementConfig is null + && bucket.Encryption.CustomerSuppliedEncryptionEnforcementConfig is null + && bucket.Encryption.GoogleManagedEncryptionEnforcementConfig is null)) + { + Console.WriteLine($"No Encryption Enforcement Configuration found for bucket {bucketName}"); + return bucket; + } + + bucket.Encryption = new Bucket.EncryptionData + { + DefaultKmsKeyName = bucket.Encryption.DefaultKmsKeyName + }; + + bucket = storage.UpdateBucket(bucket); + Console.WriteLine($"The Encryption Enforcement Configuration has been removed from the bucket {bucketName}"); + return bucket; + } +} +// [END storage_remove_all_encryption_enforcement_config] diff --git a/storage/api/Storage.Samples/BucketSetEncryptionEnforcementConfig.cs b/storage/api/Storage.Samples/BucketSetEncryptionEnforcementConfig.cs new file mode 100644 index 00000000000..885f0264f66 --- /dev/null +++ b/storage/api/Storage.Samples/BucketSetEncryptionEnforcementConfig.cs @@ -0,0 +1,82 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// [START storage_set_encryption_enforcement_config] + +using Google.Apis.Storage.v1.Data; +using Google.Cloud.Storage.V1; +using System; + +public class BucketSetEncryptionEnforcementConfigSample +{ + /// + /// Set the encryption enforcement configuration for a bucket. + /// + /// The name of the bucket. + /// + /// The full resource name of the Cloud KMS key (CMEK). + /// Required if is true. + /// + /// If true, enforces Customer-Managed Encryption Key. + /// If true, enforces Google-Managed Encryption Key. + /// If true, restricts Customer-Supplied Encryption Key. + public Bucket SetBucketEncryptionEnforcementConfig( + string bucketName = "your-unique-bucket-name", + string kmsKeyName = null, + bool enforceCmek = false, + bool enforceGmek = false, + bool restrictCsek = false) + { + var storage = StorageClient.Create(); + var bucket = storage.GetBucket(bucketName); + + if (bucket.Encryption == null) + { + bucket.Encryption = new Bucket.EncryptionData(); + } + + if (!string.IsNullOrEmpty(kmsKeyName)) + { + bucket.Encryption.DefaultKmsKeyName = kmsKeyName; + Console.WriteLine($"Default Key Set: {kmsKeyName}"); + } + else + { + bucket.Encryption.DefaultKmsKeyName = null; + Console.WriteLine("Default Key Set: None"); + } + + string cmek = enforceGmek ? "FullyRestricted" : "NotRestricted"; + string gmek = enforceCmek ? "FullyRestricted" : "NotRestricted"; + string csek = (enforceCmek || enforceGmek || restrictCsek) ? "FullyRestricted" : "NotRestricted"; + + string message = enforceCmek ? "CMEK-only enforcement policy" + : enforceGmek ? "GMEK-only enforcement policy" + : restrictCsek ? "policy to restrict CSEK" + : null; + + bucket.Encryption.CustomerManagedEncryptionEnforcementConfig = new Bucket.EncryptionData.CustomerManagedEncryptionEnforcementConfigData { RestrictionMode = cmek }; + bucket.Encryption.CustomerSuppliedEncryptionEnforcementConfig = new Bucket.EncryptionData.CustomerSuppliedEncryptionEnforcementConfigData { RestrictionMode = csek }; + bucket.Encryption.GoogleManagedEncryptionEnforcementConfig = new Bucket.EncryptionData.GoogleManagedEncryptionEnforcementConfigData { RestrictionMode = gmek }; + + if (message != null) + { + Console.WriteLine($"Bucket {bucketName} updated with {message}"); + } + + var updatedBucket = storage.UpdateBucket(bucket); + return updatedBucket; + } +} +// [END storage_set_encryption_enforcement_config] From 138aedd85a6d4f2385303d516e4039e38178e021 Mon Sep 17 00:00:00 2001 From: mahendra-google Date: Wed, 4 Mar 2026 03:20:33 -0800 Subject: [PATCH 2/8] refactor(Storage): Format console output messages to single line --- .../BucketGetEncryptionEnforcementConfig.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/storage/api/Storage.Samples/BucketGetEncryptionEnforcementConfig.cs b/storage/api/Storage.Samples/BucketGetEncryptionEnforcementConfig.cs index 062acd829c6..2c66ce2a138 100644 --- a/storage/api/Storage.Samples/BucketGetEncryptionEnforcementConfig.cs +++ b/storage/api/Storage.Samples/BucketGetEncryptionEnforcementConfig.cs @@ -39,20 +39,17 @@ public Bucket.EncryptionData BucketGetEncryptionEnforcementConfig(string bucketN var gmConfig = bucket.Encryption.GoogleManagedEncryptionEnforcementConfig; if (gmConfig != null) { - Console.WriteLine($"Google Managed (GMEK) Enforcement Restriction Mode: {gmConfig.RestrictionMode}"); - Console.WriteLine($"Google Managed (GMEK) Enforcement Effective Time: {gmConfig.EffectiveTimeRaw}"); + Console.WriteLine($"Google Managed (GMEK) Enforcement Restriction Mode: {gmConfig.RestrictionMode}, Effective Time: {gmConfig.EffectiveTimeRaw}"); } var cmConfig = bucket.Encryption.CustomerManagedEncryptionEnforcementConfig; if (cmConfig != null) { - Console.WriteLine($"Customer Managed (CMEK) Enforcement Restriction Mode: {cmConfig.RestrictionMode}"); - Console.WriteLine($"Customer Managed (CMEK) Enforcement Effective Time: {cmConfig.EffectiveTimeRaw}"); + Console.WriteLine($"Customer Managed (CMEK) Enforcement Restriction Mode: {cmConfig.RestrictionMode}, Effective Time: {cmConfig.EffectiveTimeRaw}"); } var csConfig = bucket.Encryption.CustomerSuppliedEncryptionEnforcementConfig; if (csConfig != null) { - Console.WriteLine($"Customer Supplied (CSEK) Enforcement Restriction Mode: {csConfig.RestrictionMode}"); - Console.WriteLine($"Customer Supplied (CSEK) Enforcement Effective Time: {csConfig.EffectiveTimeRaw}"); + Console.WriteLine($"Customer Supplied (CSEK) Enforcement Restriction Mode: {csConfig.RestrictionMode}, Effective Time: {csConfig.EffectiveTimeRaw}"); } return bucket.Encryption; } From 97b00ecf8079cef1c4aa4caa2d003bdcb50221f5 Mon Sep 17 00:00:00 2001 From: mahendra-google Date: Wed, 11 Mar 2026 05:26:13 -0700 Subject: [PATCH 3/8] refactor(Storage): Addressing PR review comments --- .../BucketGetEncryptionEnforcementConfigTest.cs | 4 ++-- ...ucketRemoveAllEncryptionEnforcementConfigTest.cs | 13 +++++++------ .../BucketSetEncryptionEnforcementConfigTest.cs | 10 +++++----- .../BucketRemoveAllEncryptionEnforcementConfig.cs | 6 +++--- .../BucketSetEncryptionEnforcementConfig.cs | 4 ++-- 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/storage/api/Storage.Samples.Tests/BucketGetEncryptionEnforcementConfigTest.cs b/storage/api/Storage.Samples.Tests/BucketGetEncryptionEnforcementConfigTest.cs index 7eb0841510e..eec3446b52f 100644 --- a/storage/api/Storage.Samples.Tests/BucketGetEncryptionEnforcementConfigTest.cs +++ b/storage/api/Storage.Samples.Tests/BucketGetEncryptionEnforcementConfigTest.cs @@ -33,11 +33,11 @@ public void BucketGetEncryptionEnforcementConfig() _fixture.CreateBucket(bucketName: bucketName, location: _fixture.KmsKeyLocation); string keyName = $"projects/{_fixture.ProjectId}/locations/{_fixture.KmsKeyLocation}/keyRings/{_fixture.KmsKeyRing}/cryptoKeys/{_fixture.KmsKeyName}"; - var bucket = bucketSetEncConfigSample.SetBucketEncryptionEnforcementConfig( + bucketSetEncConfigSample.SetBucketEncryptionEnforcementConfig( bucketName: bucketName, kmsKeyName: keyName, enforceCmek: true); - var bucketEncryptionData = bucketGetEncConfigSample.BucketGetEncryptionEnforcementConfig(bucket.Name); + var bucketEncryptionData = bucketGetEncConfigSample.BucketGetEncryptionEnforcementConfig(bucketName); Assert.NotNull(bucketEncryptionData); Assert.Equal(keyName, bucketEncryptionData.DefaultKmsKeyName); Assert.Multiple(() => diff --git a/storage/api/Storage.Samples.Tests/BucketRemoveAllEncryptionEnforcementConfigTest.cs b/storage/api/Storage.Samples.Tests/BucketRemoveAllEncryptionEnforcementConfigTest.cs index c0d47b8dd73..190933d9b61 100644 --- a/storage/api/Storage.Samples.Tests/BucketRemoveAllEncryptionEnforcementConfigTest.cs +++ b/storage/api/Storage.Samples.Tests/BucketRemoveAllEncryptionEnforcementConfigTest.cs @@ -32,17 +32,18 @@ public void BucketRemoveAllEncryptionEnforcementConfig() var bucketName = _fixture.GenerateBucketName(); _fixture.CreateBucket(bucketName: bucketName, location: _fixture.KmsKeyLocation); string keyName = $"projects/{_fixture.ProjectId}/locations/{_fixture.KmsKeyLocation}/keyRings/{_fixture.KmsKeyRing}/cryptoKeys/{_fixture.KmsKeyName}"; - var bucket = bucketSetEncConfigSample.SetBucketEncryptionEnforcementConfig( + + bucketSetEncConfigSample.SetBucketEncryptionEnforcementConfig( bucketName: bucketName, kmsKeyName: keyName, enforceCmek: true); - var updatedBucket = bucketRemoveEncConfigSample.BucketRemoveAllEncryptionEnforcementConfig(bucket.Name); - Assert.Equal(updatedBucket.Encryption.DefaultKmsKeyName, bucket.Encryption.DefaultKmsKeyName); + var bucketEncryptionData = bucketRemoveEncConfigSample.BucketRemoveAllEncryptionEnforcementConfig(bucketName); + Assert.Equal(keyName, bucketEncryptionData.DefaultKmsKeyName); Assert.Multiple(() => { - Assert.Null(updatedBucket.Encryption.CustomerSuppliedEncryptionEnforcementConfig); - Assert.Null(updatedBucket.Encryption.CustomerManagedEncryptionEnforcementConfig); - Assert.Null(updatedBucket.Encryption.GoogleManagedEncryptionEnforcementConfig); + Assert.Null(bucketEncryptionData.CustomerSuppliedEncryptionEnforcementConfig); + Assert.Null(bucketEncryptionData.CustomerManagedEncryptionEnforcementConfig); + Assert.Null(bucketEncryptionData.GoogleManagedEncryptionEnforcementConfig); }); } } diff --git a/storage/api/Storage.Samples.Tests/BucketSetEncryptionEnforcementConfigTest.cs b/storage/api/Storage.Samples.Tests/BucketSetEncryptionEnforcementConfigTest.cs index 9f4d7d4a5d5..b7eaf5d3c63 100644 --- a/storage/api/Storage.Samples.Tests/BucketSetEncryptionEnforcementConfigTest.cs +++ b/storage/api/Storage.Samples.Tests/BucketSetEncryptionEnforcementConfigTest.cs @@ -39,7 +39,7 @@ public void BucketSetEncryptionEnforcementConfig( ? $"projects/{_fixture.ProjectId}/locations/{_fixture.KmsKeyLocation}/keyRings/{_fixture.KmsKeyRing}/cryptoKeys/{_fixture.KmsKeyName}" : null; _fixture.CreateBucket(bucketName: bucketName, location: _fixture.KmsKeyLocation); - var bucket = bucketSetEncConfigSample.SetBucketEncryptionEnforcementConfig( + var bucketEncryptionData = bucketSetEncConfigSample.SetBucketEncryptionEnforcementConfig( bucketName: bucketName, kmsKeyName: keyName, enforceCmek: enforceCmek, @@ -52,11 +52,11 @@ public void BucketSetEncryptionEnforcementConfig( Assert.Multiple(() => { - Assert.Equal(expectedCmek, bucket.Encryption.CustomerManagedEncryptionEnforcementConfig?.RestrictionMode); - Assert.Equal(expectedCsek, bucket.Encryption.CustomerSuppliedEncryptionEnforcementConfig?.RestrictionMode); - Assert.Equal(expectedGmek, bucket.Encryption.GoogleManagedEncryptionEnforcementConfig?.RestrictionMode); + Assert.Equal(expectedCmek, bucketEncryptionData.CustomerManagedEncryptionEnforcementConfig?.RestrictionMode); + Assert.Equal(expectedCsek, bucketEncryptionData.CustomerSuppliedEncryptionEnforcementConfig?.RestrictionMode); + Assert.Equal(expectedGmek, bucketEncryptionData.GoogleManagedEncryptionEnforcementConfig?.RestrictionMode); - if (enforceCmek) Assert.Equal(keyName, bucket.Encryption.DefaultKmsKeyName); + if (enforceCmek) Assert.Equal(keyName, bucketEncryptionData.DefaultKmsKeyName); }); } } diff --git a/storage/api/Storage.Samples/BucketRemoveAllEncryptionEnforcementConfig.cs b/storage/api/Storage.Samples/BucketRemoveAllEncryptionEnforcementConfig.cs index 9af55630ba8..e8e0b58e911 100644 --- a/storage/api/Storage.Samples/BucketRemoveAllEncryptionEnforcementConfig.cs +++ b/storage/api/Storage.Samples/BucketRemoveAllEncryptionEnforcementConfig.cs @@ -24,7 +24,7 @@ public class BucketRemoveAllEncryptionEnforcementConfigSample /// Remove all encryption enforcement configurations from the bucket. /// /// The name of the bucket. - public Bucket BucketRemoveAllEncryptionEnforcementConfig(string bucketName = "your-unique-bucket-name") + public Bucket.EncryptionData BucketRemoveAllEncryptionEnforcementConfig(string bucketName = "your-unique-bucket-name") { var storage = StorageClient.Create(); var bucket = storage.GetBucket(bucketName); @@ -35,7 +35,7 @@ public Bucket BucketRemoveAllEncryptionEnforcementConfig(string bucketName = "yo && bucket.Encryption.GoogleManagedEncryptionEnforcementConfig is null)) { Console.WriteLine($"No Encryption Enforcement Configuration found for bucket {bucketName}"); - return bucket; + return bucket.Encryption; } bucket.Encryption = new Bucket.EncryptionData @@ -45,7 +45,7 @@ public Bucket BucketRemoveAllEncryptionEnforcementConfig(string bucketName = "yo bucket = storage.UpdateBucket(bucket); Console.WriteLine($"The Encryption Enforcement Configuration has been removed from the bucket {bucketName}"); - return bucket; + return bucket.Encryption; } } // [END storage_remove_all_encryption_enforcement_config] diff --git a/storage/api/Storage.Samples/BucketSetEncryptionEnforcementConfig.cs b/storage/api/Storage.Samples/BucketSetEncryptionEnforcementConfig.cs index 885f0264f66..2ebf33497b2 100644 --- a/storage/api/Storage.Samples/BucketSetEncryptionEnforcementConfig.cs +++ b/storage/api/Storage.Samples/BucketSetEncryptionEnforcementConfig.cs @@ -31,7 +31,7 @@ public class BucketSetEncryptionEnforcementConfigSample /// If true, enforces Customer-Managed Encryption Key. /// If true, enforces Google-Managed Encryption Key. /// If true, restricts Customer-Supplied Encryption Key. - public Bucket SetBucketEncryptionEnforcementConfig( + public Bucket.EncryptionData SetBucketEncryptionEnforcementConfig( string bucketName = "your-unique-bucket-name", string kmsKeyName = null, bool enforceCmek = false, @@ -76,7 +76,7 @@ public Bucket SetBucketEncryptionEnforcementConfig( } var updatedBucket = storage.UpdateBucket(bucket); - return updatedBucket; + return updatedBucket.Encryption; } } // [END storage_set_encryption_enforcement_config] From c59443ea2ba536cb45172a5f702f5fd49b33bdda Mon Sep 17 00:00:00 2001 From: mahendra-google Date: Sun, 22 Mar 2026 22:37:20 -0700 Subject: [PATCH 4/8] chore(Storage): Update names of region tags --- .../Storage.Samples/BucketGetEncryptionEnforcementConfig.cs | 6 +++--- .../Storage.Samples/BucketSetEncryptionEnforcementConfig.cs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/storage/api/Storage.Samples/BucketGetEncryptionEnforcementConfig.cs b/storage/api/Storage.Samples/BucketGetEncryptionEnforcementConfig.cs index 2c66ce2a138..2fc298a4666 100644 --- a/storage/api/Storage.Samples/BucketGetEncryptionEnforcementConfig.cs +++ b/storage/api/Storage.Samples/BucketGetEncryptionEnforcementConfig.cs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// [START storage_get_encryption_enforcement_config] +// [START storage_get_bucket_encryption_enforcement_config] using Google.Apis.Storage.v1.Data; using Google.Cloud.Storage.V1; @@ -32,7 +32,7 @@ public Bucket.EncryptionData BucketGetEncryptionEnforcementConfig(string bucketN if (bucket.Encryption == null) { - Console.WriteLine("No Encryption Configuration is found (Default GMEK is active)"); + Console.WriteLine("No Encryption Enforcement Configuration is found"); return bucket.Encryption; } @@ -54,4 +54,4 @@ public Bucket.EncryptionData BucketGetEncryptionEnforcementConfig(string bucketN return bucket.Encryption; } } -// [END storage_get_encryption_enforcement_config] +// [END storage_get_bucket_encryption_enforcement_config] diff --git a/storage/api/Storage.Samples/BucketSetEncryptionEnforcementConfig.cs b/storage/api/Storage.Samples/BucketSetEncryptionEnforcementConfig.cs index 2ebf33497b2..a049ac0f2c1 100644 --- a/storage/api/Storage.Samples/BucketSetEncryptionEnforcementConfig.cs +++ b/storage/api/Storage.Samples/BucketSetEncryptionEnforcementConfig.cs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// [START storage_set_encryption_enforcement_config] +// [START storage_set_bucket_encryption_enforcement_config] using Google.Apis.Storage.v1.Data; using Google.Cloud.Storage.V1; @@ -79,4 +79,4 @@ public Bucket.EncryptionData SetBucketEncryptionEnforcementConfig( return updatedBucket.Encryption; } } -// [END storage_set_encryption_enforcement_config] +// [END storage_set_bucket_encryption_enforcement_config] From 40518ba0f0d1cba52fc7b28046acfd34ce33c57a Mon Sep 17 00:00:00 2001 From: mahendra-google Date: Mon, 23 Mar 2026 00:50:13 -0700 Subject: [PATCH 5/8] chore(Storage): Modify bucket update encryption enforcement sample --- ...ucketUpdateEncryptionEnforcementConfig.cs} | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) rename storage/api/Storage.Samples/{BucketRemoveAllEncryptionEnforcementConfig.cs => BucketUpdateEncryptionEnforcementConfig.cs} (71%) diff --git a/storage/api/Storage.Samples/BucketRemoveAllEncryptionEnforcementConfig.cs b/storage/api/Storage.Samples/BucketUpdateEncryptionEnforcementConfig.cs similarity index 71% rename from storage/api/Storage.Samples/BucketRemoveAllEncryptionEnforcementConfig.cs rename to storage/api/Storage.Samples/BucketUpdateEncryptionEnforcementConfig.cs index e8e0b58e911..b14a8b8a29c 100644 --- a/storage/api/Storage.Samples/BucketRemoveAllEncryptionEnforcementConfig.cs +++ b/storage/api/Storage.Samples/BucketUpdateEncryptionEnforcementConfig.cs @@ -12,19 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -// [START storage_remove_all_encryption_enforcement_config] +// [START storage_update_bucket_encryption_enforcement_config] using Google.Apis.Storage.v1.Data; using Google.Cloud.Storage.V1; using System; -public class BucketRemoveAllEncryptionEnforcementConfigSample +public class BucketUpdateEncryptionEnforcementConfigSample { /// - /// Remove all encryption enforcement configurations from the bucket. + /// Updates the encryption enforcement configurations of the bucket. /// /// The name of the bucket. - public Bucket.EncryptionData BucketRemoveAllEncryptionEnforcementConfig(string bucketName = "your-unique-bucket-name") + /// The encryption configuration for the bucket. + public Bucket.EncryptionData BucketUpdateEncryptionEnforcementConfig(string bucketName = "your-unique-bucket-name", Bucket.EncryptionData encryptionData = null) { var storage = StorageClient.Create(); var bucket = storage.GetBucket(bucketName); @@ -38,14 +39,10 @@ public Bucket.EncryptionData BucketRemoveAllEncryptionEnforcementConfig(string b return bucket.Encryption; } - bucket.Encryption = new Bucket.EncryptionData - { - DefaultKmsKeyName = bucket.Encryption.DefaultKmsKeyName - }; - + bucket.Encryption = encryptionData; bucket = storage.UpdateBucket(bucket); - Console.WriteLine($"The Encryption Enforcement Configuration has been removed from the bucket {bucketName}"); + Console.WriteLine($"The Encryption Enforcement Configuration has been updated for the bucket {bucketName}"); return bucket.Encryption; } } -// [END storage_remove_all_encryption_enforcement_config] +// [END storage_update_bucket_encryption_enforcement_config] From 4445cf5f6a8f1060db3b8a9d1372a6eb0957478f Mon Sep 17 00:00:00 2001 From: mahendra-google Date: Mon, 23 Mar 2026 03:45:38 -0700 Subject: [PATCH 6/8] chore(Storage): Modify smaple and test for update encryption config --- ...tUpdateEncryptionEnforcementConfigTest.cs} | 39 +++++++++++++------ ...BucketUpdateEncryptionEnforcementConfig.cs | 2 +- 2 files changed, 29 insertions(+), 12 deletions(-) rename storage/api/Storage.Samples.Tests/{BucketRemoveAllEncryptionEnforcementConfigTest.cs => BucketUpdateEncryptionEnforcementConfigTest.cs} (52%) diff --git a/storage/api/Storage.Samples.Tests/BucketRemoveAllEncryptionEnforcementConfigTest.cs b/storage/api/Storage.Samples.Tests/BucketUpdateEncryptionEnforcementConfigTest.cs similarity index 52% rename from storage/api/Storage.Samples.Tests/BucketRemoveAllEncryptionEnforcementConfigTest.cs rename to storage/api/Storage.Samples.Tests/BucketUpdateEncryptionEnforcementConfigTest.cs index 190933d9b61..ebf9b3efbfd 100644 --- a/storage/api/Storage.Samples.Tests/BucketRemoveAllEncryptionEnforcementConfigTest.cs +++ b/storage/api/Storage.Samples.Tests/BucketUpdateEncryptionEnforcementConfigTest.cs @@ -12,23 +12,26 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Google.Apis.Storage.v1.Data; using Xunit; [Collection(nameof(StorageFixture))] -public class BucketRemoveAllEncryptionEnforcementConfigTest +public class BucketUpdateEncryptionEnforcementConfigTest { private readonly StorageFixture _fixture; - public BucketRemoveAllEncryptionEnforcementConfigTest(StorageFixture fixture) + public BucketUpdateEncryptionEnforcementConfigTest(StorageFixture fixture) { _fixture = fixture; } - [Fact] - public void BucketRemoveAllEncryptionEnforcementConfig() + [Theory] + [InlineData("FullyRestricted")] + [InlineData(null)] + public void BucketUpdateEncryptionEnforcementConfig(string restrictionMode) { var bucketSetEncConfigSample = new BucketSetEncryptionEnforcementConfigSample(); - var bucketRemoveEncConfigSample = new BucketRemoveAllEncryptionEnforcementConfigSample(); + var bucketUpdateEncConfigSample = new BucketUpdateEncryptionEnforcementConfigSample(); var bucketName = _fixture.GenerateBucketName(); _fixture.CreateBucket(bucketName: bucketName, location: _fixture.KmsKeyLocation); string keyName = $"projects/{_fixture.ProjectId}/locations/{_fixture.KmsKeyLocation}/keyRings/{_fixture.KmsKeyRing}/cryptoKeys/{_fixture.KmsKeyName}"; @@ -37,13 +40,27 @@ public void BucketRemoveAllEncryptionEnforcementConfig() bucketName: bucketName, kmsKeyName: keyName, enforceCmek: true); - var bucketEncryptionData = bucketRemoveEncConfigSample.BucketRemoveAllEncryptionEnforcementConfig(bucketName); + + var encryptionData = new Bucket.EncryptionData + { + DefaultKmsKeyName = keyName, + GoogleManagedEncryptionEnforcementConfig = restrictionMode != null + ? new Bucket.EncryptionData.GoogleManagedEncryptionEnforcementConfigData + { RestrictionMode = restrictionMode } + : null + }; + + var bucketEncryptionData = bucketUpdateEncConfigSample.BucketUpdateEncryptionEnforcementConfig(bucketName, encryptionData); Assert.Equal(keyName, bucketEncryptionData.DefaultKmsKeyName); - Assert.Multiple(() => + + if (restrictionMode != null) + { + Assert.NotNull(encryptionData.GoogleManagedEncryptionEnforcementConfig); + Assert.Equal(restrictionMode, encryptionData.GoogleManagedEncryptionEnforcementConfig.RestrictionMode); + } + else { - Assert.Null(bucketEncryptionData.CustomerSuppliedEncryptionEnforcementConfig); - Assert.Null(bucketEncryptionData.CustomerManagedEncryptionEnforcementConfig); - Assert.Null(bucketEncryptionData.GoogleManagedEncryptionEnforcementConfig); - }); + Assert.Null(encryptionData.GoogleManagedEncryptionEnforcementConfig); + } } } diff --git a/storage/api/Storage.Samples/BucketUpdateEncryptionEnforcementConfig.cs b/storage/api/Storage.Samples/BucketUpdateEncryptionEnforcementConfig.cs index b14a8b8a29c..773e5400a51 100644 --- a/storage/api/Storage.Samples/BucketUpdateEncryptionEnforcementConfig.cs +++ b/storage/api/Storage.Samples/BucketUpdateEncryptionEnforcementConfig.cs @@ -21,7 +21,7 @@ public class BucketUpdateEncryptionEnforcementConfigSample { /// - /// Updates the encryption enforcement configurations of the bucket. + /// Updates the encryption enforcement configuration of the bucket. /// /// The name of the bucket. /// The encryption configuration for the bucket. From b3b17dbdac7ca2211195c8c14c36775d20968520 Mon Sep 17 00:00:00 2001 From: mahendra-google Date: Mon, 23 Mar 2026 04:42:24 -0700 Subject: [PATCH 7/8] chore(Storage): Addressing Review Feedback Comments --- .../BucketSetEncryptionEnforcementConfigTest.cs | 11 ++++++----- .../BucketSetEncryptionEnforcementConfig.cs | 14 +++++++------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/storage/api/Storage.Samples.Tests/BucketSetEncryptionEnforcementConfigTest.cs b/storage/api/Storage.Samples.Tests/BucketSetEncryptionEnforcementConfigTest.cs index b7eaf5d3c63..dca99adbb21 100644 --- a/storage/api/Storage.Samples.Tests/BucketSetEncryptionEnforcementConfigTest.cs +++ b/storage/api/Storage.Samples.Tests/BucketSetEncryptionEnforcementConfigTest.cs @@ -31,7 +31,7 @@ public BucketSetEncryptionEnforcementConfigTest(StorageFixture fixture) public void BucketSetEncryptionEnforcementConfig( bool enforceCmek, bool enforceGmek, - bool restrictCsek) + bool enforceCsek) { var bucketSetEncConfigSample = new BucketSetEncryptionEnforcementConfigSample(); var bucketName = _fixture.GenerateBucketName(); @@ -44,11 +44,12 @@ public void BucketSetEncryptionEnforcementConfig( kmsKeyName: keyName, enforceCmek: enforceCmek, enforceGmek: enforceGmek, - restrictCsek: restrictCsek); + enforceCsek: enforceCsek); + + string expectedCmek = (enforceGmek || enforceCsek) ? "FullyRestricted" : "NotRestricted"; + string expectedGmek = (enforceCmek || enforceCsek) ? "FullyRestricted" : "NotRestricted"; + string expectedCsek = (enforceCmek || enforceGmek) ? "FullyRestricted" : "NotRestricted"; - string expectedCmek = enforceGmek ? "FullyRestricted" : "NotRestricted"; - string expectedGmek = enforceCmek ? "FullyRestricted" : "NotRestricted"; - string expectedCsek = (enforceCmek || enforceGmek || restrictCsek) ? "FullyRestricted" : "NotRestricted"; Assert.Multiple(() => { diff --git a/storage/api/Storage.Samples/BucketSetEncryptionEnforcementConfig.cs b/storage/api/Storage.Samples/BucketSetEncryptionEnforcementConfig.cs index a049ac0f2c1..65f99e2f74b 100644 --- a/storage/api/Storage.Samples/BucketSetEncryptionEnforcementConfig.cs +++ b/storage/api/Storage.Samples/BucketSetEncryptionEnforcementConfig.cs @@ -30,13 +30,13 @@ public class BucketSetEncryptionEnforcementConfigSample /// /// If true, enforces Customer-Managed Encryption Key. /// If true, enforces Google-Managed Encryption Key. - /// If true, restricts Customer-Supplied Encryption Key. + /// If true, enforces Customer-Supplied Encryption Key. public Bucket.EncryptionData SetBucketEncryptionEnforcementConfig( string bucketName = "your-unique-bucket-name", string kmsKeyName = null, bool enforceCmek = false, bool enforceGmek = false, - bool restrictCsek = false) + bool enforceCsek = false) { var storage = StorageClient.Create(); var bucket = storage.GetBucket(bucketName); @@ -57,14 +57,14 @@ public Bucket.EncryptionData SetBucketEncryptionEnforcementConfig( Console.WriteLine("Default Key Set: None"); } - string cmek = enforceGmek ? "FullyRestricted" : "NotRestricted"; - string gmek = enforceCmek ? "FullyRestricted" : "NotRestricted"; - string csek = (enforceCmek || enforceGmek || restrictCsek) ? "FullyRestricted" : "NotRestricted"; + string cmek = (enforceGmek || enforceCsek) ? "FullyRestricted" : "NotRestricted"; + string gmek = (enforceCmek || enforceCsek) ? "FullyRestricted" : "NotRestricted"; + string csek = (enforceCmek || enforceGmek) ? "FullyRestricted" : "NotRestricted"; string message = enforceCmek ? "CMEK-only enforcement policy" : enforceGmek ? "GMEK-only enforcement policy" - : restrictCsek ? "policy to restrict CSEK" - : null; + : enforceCsek ? "CSEK-only enforcement policy" + : "no encryption enforcement policy"; bucket.Encryption.CustomerManagedEncryptionEnforcementConfig = new Bucket.EncryptionData.CustomerManagedEncryptionEnforcementConfigData { RestrictionMode = cmek }; bucket.Encryption.CustomerSuppliedEncryptionEnforcementConfig = new Bucket.EncryptionData.CustomerSuppliedEncryptionEnforcementConfigData { RestrictionMode = csek }; From cf77cb74b6d5eaa3996cbadc6e70f3ac9d1c6d82 Mon Sep 17 00:00:00 2001 From: mahendra-google Date: Mon, 23 Mar 2026 23:16:39 -0700 Subject: [PATCH 8/8] chore(Storage): Remove one extra blank line --- .../BucketSetEncryptionEnforcementConfigTest.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/storage/api/Storage.Samples.Tests/BucketSetEncryptionEnforcementConfigTest.cs b/storage/api/Storage.Samples.Tests/BucketSetEncryptionEnforcementConfigTest.cs index dca99adbb21..204e51aa86b 100644 --- a/storage/api/Storage.Samples.Tests/BucketSetEncryptionEnforcementConfigTest.cs +++ b/storage/api/Storage.Samples.Tests/BucketSetEncryptionEnforcementConfigTest.cs @@ -50,7 +50,6 @@ public void BucketSetEncryptionEnforcementConfig( string expectedGmek = (enforceCmek || enforceCsek) ? "FullyRestricted" : "NotRestricted"; string expectedCsek = (enforceCmek || enforceGmek) ? "FullyRestricted" : "NotRestricted"; - Assert.Multiple(() => { Assert.Equal(expectedCmek, bucketEncryptionData.CustomerManagedEncryptionEnforcementConfig?.RestrictionMode);