diff --git a/storage/api/Storage.Samples.Tests/BucketGetEncryptionEnforcementConfigTest.cs b/storage/api/Storage.Samples.Tests/BucketGetEncryptionEnforcementConfigTest.cs new file mode 100644 index 00000000000..eec3446b52f --- /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}"; + bucketSetEncConfigSample.SetBucketEncryptionEnforcementConfig( + bucketName: bucketName, + kmsKeyName: keyName, + enforceCmek: true); + var bucketEncryptionData = bucketGetEncConfigSample.BucketGetEncryptionEnforcementConfig(bucketName); + 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/BucketSetEncryptionEnforcementConfigTest.cs b/storage/api/Storage.Samples.Tests/BucketSetEncryptionEnforcementConfigTest.cs new file mode 100644 index 00000000000..204e51aa86b --- /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 enforceCsek) + { + 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 bucketEncryptionData = bucketSetEncConfigSample.SetBucketEncryptionEnforcementConfig( + bucketName: bucketName, + kmsKeyName: keyName, + enforceCmek: enforceCmek, + enforceGmek: enforceGmek, + enforceCsek: enforceCsek); + + string expectedCmek = (enforceGmek || enforceCsek) ? "FullyRestricted" : "NotRestricted"; + string expectedGmek = (enforceCmek || enforceCsek) ? "FullyRestricted" : "NotRestricted"; + string expectedCsek = (enforceCmek || enforceGmek) ? "FullyRestricted" : "NotRestricted"; + + Assert.Multiple(() => + { + Assert.Equal(expectedCmek, bucketEncryptionData.CustomerManagedEncryptionEnforcementConfig?.RestrictionMode); + Assert.Equal(expectedCsek, bucketEncryptionData.CustomerSuppliedEncryptionEnforcementConfig?.RestrictionMode); + Assert.Equal(expectedGmek, bucketEncryptionData.GoogleManagedEncryptionEnforcementConfig?.RestrictionMode); + + if (enforceCmek) Assert.Equal(keyName, bucketEncryptionData.DefaultKmsKeyName); + }); + } +} diff --git a/storage/api/Storage.Samples.Tests/BucketUpdateEncryptionEnforcementConfigTest.cs b/storage/api/Storage.Samples.Tests/BucketUpdateEncryptionEnforcementConfigTest.cs new file mode 100644 index 00000000000..ebf9b3efbfd --- /dev/null +++ b/storage/api/Storage.Samples.Tests/BucketUpdateEncryptionEnforcementConfigTest.cs @@ -0,0 +1,66 @@ +// 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 Google.Apis.Storage.v1.Data; +using Xunit; + +[Collection(nameof(StorageFixture))] +public class BucketUpdateEncryptionEnforcementConfigTest +{ + private readonly StorageFixture _fixture; + + public BucketUpdateEncryptionEnforcementConfigTest(StorageFixture fixture) + { + _fixture = fixture; + } + + [Theory] + [InlineData("FullyRestricted")] + [InlineData(null)] + public void BucketUpdateEncryptionEnforcementConfig(string restrictionMode) + { + var bucketSetEncConfigSample = new BucketSetEncryptionEnforcementConfigSample(); + 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}"; + + bucketSetEncConfigSample.SetBucketEncryptionEnforcementConfig( + bucketName: bucketName, + kmsKeyName: keyName, + enforceCmek: true); + + 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); + + if (restrictionMode != null) + { + Assert.NotNull(encryptionData.GoogleManagedEncryptionEnforcementConfig); + Assert.Equal(restrictionMode, encryptionData.GoogleManagedEncryptionEnforcementConfig.RestrictionMode); + } + else + { + Assert.Null(encryptionData.GoogleManagedEncryptionEnforcementConfig); + } + } +} diff --git a/storage/api/Storage.Samples/BucketGetEncryptionEnforcementConfig.cs b/storage/api/Storage.Samples/BucketGetEncryptionEnforcementConfig.cs new file mode 100644 index 00000000000..2fc298a4666 --- /dev/null +++ b/storage/api/Storage.Samples/BucketGetEncryptionEnforcementConfig.cs @@ -0,0 +1,57 @@ +// 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_bucket_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 Enforcement Configuration is found"); + return bucket.Encryption; + } + + var gmConfig = bucket.Encryption.GoogleManagedEncryptionEnforcementConfig; + if (gmConfig != null) + { + 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}, Effective Time: {cmConfig.EffectiveTimeRaw}"); + } + var csConfig = bucket.Encryption.CustomerSuppliedEncryptionEnforcementConfig; + if (csConfig != null) + { + Console.WriteLine($"Customer Supplied (CSEK) Enforcement Restriction Mode: {csConfig.RestrictionMode}, Effective Time: {csConfig.EffectiveTimeRaw}"); + } + return bucket.Encryption; + } +} +// [END storage_get_bucket_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..65f99e2f74b --- /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_bucket_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, 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 enforceCsek = 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 || 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" + : 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 }; + 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.Encryption; + } +} +// [END storage_set_bucket_encryption_enforcement_config] diff --git a/storage/api/Storage.Samples/BucketUpdateEncryptionEnforcementConfig.cs b/storage/api/Storage.Samples/BucketUpdateEncryptionEnforcementConfig.cs new file mode 100644 index 00000000000..773e5400a51 --- /dev/null +++ b/storage/api/Storage.Samples/BucketUpdateEncryptionEnforcementConfig.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. + +// [START storage_update_bucket_encryption_enforcement_config] + +using Google.Apis.Storage.v1.Data; +using Google.Cloud.Storage.V1; +using System; + +public class BucketUpdateEncryptionEnforcementConfigSample +{ + /// + /// Updates the encryption enforcement configuration of the bucket. + /// + /// The name of the bucket. + /// 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); + + 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.Encryption; + } + + bucket.Encryption = encryptionData; + bucket = storage.UpdateBucket(bucket); + Console.WriteLine($"The Encryption Enforcement Configuration has been updated for the bucket {bucketName}"); + return bucket.Encryption; + } +} +// [END storage_update_bucket_encryption_enforcement_config]