diff --git a/samples/snippets/src/main/java/com/example/storage/bucket/GetBucketEncryptionEnforcementConfig.java b/samples/snippets/src/main/java/com/example/storage/bucket/GetBucketEncryptionEnforcementConfig.java new file mode 100644 index 0000000000..fcc0bde727 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/storage/bucket/GetBucketEncryptionEnforcementConfig.java @@ -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. + */ + +package com.example.storage.bucket; + +// [START storage_get_bucket_encryption_enforcement_config] + +import com.google.cloud.storage.Bucket; +import com.google.cloud.storage.BucketInfo.CustomerManagedEncryptionEnforcementConfig; +import com.google.cloud.storage.BucketInfo.CustomerSuppliedEncryptionEnforcementConfig; +import com.google.cloud.storage.BucketInfo.GoogleManagedEncryptionEnforcementConfig; +import com.google.cloud.storage.Storage; +import com.google.cloud.storage.StorageOptions; + +public class GetBucketEncryptionEnforcementConfig { + public static void getBucketEncryptionEnforcementConfig(String projectId, String bucketName) + throws Exception { + // The ID of your GCP project + // String projectId = "your-project-id"; + + // The ID of your GCS bucket + // String bucketName = "your-unique-bucket-name"; + + try (Storage storage = + StorageOptions.newBuilder().setProjectId(projectId).build().getService()) { + System.out.println( + "\n--- Getting Encryption Enforcement Policy for bucket " + bucketName + " ---"); + + Bucket bucket = storage.get(bucketName); + + if (bucket == null) { + System.out.println("Bucket " + bucketName + " not found."); + return; + } + + System.out.println("Bucket Name: " + bucket.getName()); + + GoogleManagedEncryptionEnforcementConfig gmekConfig = + bucket.getGoogleManagedEncryptionEnforcementConfig(); + CustomerManagedEncryptionEnforcementConfig cmekConfig = + bucket.getCustomerManagedEncryptionEnforcementConfig(); + CustomerSuppliedEncryptionEnforcementConfig csekConfig = + bucket.getCustomerSuppliedEncryptionEnforcementConfig(); + + System.out.println( + " GMEK Enforcement: " + + (gmekConfig != null + ? String.format( + "Mode: %s, Effective Time: %s", + gmekConfig.getRestrictionMode(), gmekConfig.getEffectiveTime()) + : "NOT SET (Default)")); + System.out.println( + " CMEK Enforcement: " + + (cmekConfig != null + ? String.format( + "Mode: %s, Effective Time: %s", + cmekConfig.getRestrictionMode(), cmekConfig.getEffectiveTime()) + : "NOT SET (Default)")); + System.out.println( + " CSEK Enforcement: " + + (csekConfig != null + ? String.format( + "Mode: %s, Effective Time: %s", + csekConfig.getRestrictionMode(), csekConfig.getEffectiveTime()) + : "NOT SET (Default)")); + } + } +} +// [END storage_get_bucket_encryption_enforcement_config] diff --git a/samples/snippets/src/main/java/com/example/storage/bucket/SetBucketEncryptionEnforcementConfig.java b/samples/snippets/src/main/java/com/example/storage/bucket/SetBucketEncryptionEnforcementConfig.java new file mode 100644 index 0000000000..98fb5209b4 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/storage/bucket/SetBucketEncryptionEnforcementConfig.java @@ -0,0 +1,113 @@ +/* + * 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. + */ + +package com.example.storage.bucket; + +// [START storage_set_bucket_encryption_enforcement_config] + +import com.google.cloud.storage.Bucket; +import com.google.cloud.storage.BucketInfo; +import com.google.cloud.storage.BucketInfo.CustomerManagedEncryptionEnforcementConfig; +import com.google.cloud.storage.BucketInfo.CustomerSuppliedEncryptionEnforcementConfig; +import com.google.cloud.storage.BucketInfo.EncryptionEnforcementRestrictionMode; +import com.google.cloud.storage.BucketInfo.GoogleManagedEncryptionEnforcementConfig; +import com.google.cloud.storage.Storage; +import com.google.cloud.storage.StorageOptions; + +public class SetBucketEncryptionEnforcementConfig { + public static void setBucketEncryptionEnforcementConfig(String projectId, String bucketName) + throws Exception { + // The ID of your GCP project + // String projectId = "your-project-id"; + + // The ID of your GCS bucket + // String bucketName = "your-unique-bucket-name"; + + try (Storage storage = + StorageOptions.newBuilder().setProjectId(projectId).build().getService()) { + + // Example 1: Enforce GMEK Only + setGmekEnforcedPolicy(storage, "g-" + bucketName); + + // Example 2: Enforce CMEK Only + setCmekEnforcedPolicy(storage, "c-" + bucketName); + + // Example 3: Restrict CSEK (Ransomware Protection) + restrictCsekPolicy(storage, "rc-" + bucketName); + } + } + + public static void setGmekEnforcedPolicy(Storage storage, String bucketName) { + GoogleManagedEncryptionEnforcementConfig gmekConfig = + GoogleManagedEncryptionEnforcementConfig.of( + EncryptionEnforcementRestrictionMode.NOT_RESTRICTED); + CustomerManagedEncryptionEnforcementConfig cmekConfig = + CustomerManagedEncryptionEnforcementConfig.of( + EncryptionEnforcementRestrictionMode.FULLY_RESTRICTED); + CustomerSuppliedEncryptionEnforcementConfig csekConfig = + CustomerSuppliedEncryptionEnforcementConfig.of( + EncryptionEnforcementRestrictionMode.FULLY_RESTRICTED); + + BucketInfo bucketInfo = + BucketInfo.newBuilder(bucketName) + .setGoogleManagedEncryptionEnforcementConfig(gmekConfig) + .setCustomerManagedEncryptionEnforcementConfig(cmekConfig) + .setCustomerSuppliedEncryptionEnforcementConfig(csekConfig) + .build(); + + Bucket bucket = storage.create(bucketInfo); + System.out.println( + "Bucket " + bucket.getName() + " created with GMEK-only enforcement policy."); + } + + public static void setCmekEnforcedPolicy(Storage storage, String bucketName) { + GoogleManagedEncryptionEnforcementConfig gmekConfig = + GoogleManagedEncryptionEnforcementConfig.of( + EncryptionEnforcementRestrictionMode.FULLY_RESTRICTED); + CustomerManagedEncryptionEnforcementConfig cmekConfig = + CustomerManagedEncryptionEnforcementConfig.of( + EncryptionEnforcementRestrictionMode.NOT_RESTRICTED); + CustomerSuppliedEncryptionEnforcementConfig csekConfig = + CustomerSuppliedEncryptionEnforcementConfig.of( + EncryptionEnforcementRestrictionMode.FULLY_RESTRICTED); + + BucketInfo bucketInfo = + BucketInfo.newBuilder(bucketName) + .setGoogleManagedEncryptionEnforcementConfig(gmekConfig) + .setCustomerManagedEncryptionEnforcementConfig(cmekConfig) + .setCustomerSuppliedEncryptionEnforcementConfig(csekConfig) + .build(); + + Bucket bucket = storage.create(bucketInfo); + System.out.println( + "Bucket " + bucket.getName() + " created with CMEK-only enforcement policy."); + } + + public static void restrictCsekPolicy(Storage storage, String bucketName) { + CustomerSuppliedEncryptionEnforcementConfig csekConfig = + CustomerSuppliedEncryptionEnforcementConfig.of( + EncryptionEnforcementRestrictionMode.FULLY_RESTRICTED); + + BucketInfo bucketInfo = + BucketInfo.newBuilder(bucketName) + .setCustomerSuppliedEncryptionEnforcementConfig(csekConfig) + .build(); + + Bucket bucket = storage.create(bucketInfo); + System.out.println("Bucket " + bucket.getName() + " created with a policy to restrict CSEK."); + } +} +// [END storage_set_bucket_encryption_enforcement_config] diff --git a/samples/snippets/src/main/java/com/example/storage/bucket/UpdateBucketEncryptionEnforcementConfig.java b/samples/snippets/src/main/java/com/example/storage/bucket/UpdateBucketEncryptionEnforcementConfig.java new file mode 100644 index 0000000000..0b2c62cc1b --- /dev/null +++ b/samples/snippets/src/main/java/com/example/storage/bucket/UpdateBucketEncryptionEnforcementConfig.java @@ -0,0 +1,74 @@ +/* + * 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. + */ + +package com.example.storage.bucket; + +// [START storage_update_bucket_encryption_enforcement_config] + +import com.google.cloud.storage.Bucket; +import com.google.cloud.storage.BucketInfo.CustomerManagedEncryptionEnforcementConfig; +import com.google.cloud.storage.BucketInfo.CustomerSuppliedEncryptionEnforcementConfig; +import com.google.cloud.storage.BucketInfo.EncryptionEnforcementRestrictionMode; +import com.google.cloud.storage.BucketInfo.GoogleManagedEncryptionEnforcementConfig; +import com.google.cloud.storage.Storage; +import com.google.cloud.storage.StorageOptions; + +public class UpdateBucketEncryptionEnforcementConfig { + public static void updateBucketEncryptionEnforcementConfig(String projectId, String bucketName) + throws Exception { + // The ID of your GCP project + // String projectId = "your-project-id"; + + // The ID of your GCS bucket with CMEK and CSEK restricted + // String bucketName = "your-unique-bucket-name"; + + try (Storage storage = + StorageOptions.newBuilder().setProjectId(projectId).build().getService()) { + + Bucket bucket = storage.get(bucketName); + if (bucket == null) { + System.out.println("Bucket " + bucketName + " not found."); + return; + } + + // 1. Update a specific type (e.g., change GMEK to FULLY_RESTRICTED) + GoogleManagedEncryptionEnforcementConfig newGmekConfig = + GoogleManagedEncryptionEnforcementConfig.of( + EncryptionEnforcementRestrictionMode.FULLY_RESTRICTED); + + // 2. Remove a specific type (e.g., remove CMEK enforcement) + CustomerManagedEncryptionEnforcementConfig newCmekConfig = + CustomerManagedEncryptionEnforcementConfig.of( + EncryptionEnforcementRestrictionMode.NOT_RESTRICTED); + + // For the update, need to specify all three configs, so keeping this same as before + CustomerSuppliedEncryptionEnforcementConfig sameCsekConfig = + CustomerSuppliedEncryptionEnforcementConfig.of( + EncryptionEnforcementRestrictionMode.FULLY_RESTRICTED); + + bucket.toBuilder() + .setGoogleManagedEncryptionEnforcementConfig(newGmekConfig) + .setCustomerManagedEncryptionEnforcementConfig(newCmekConfig) + .setCustomerSuppliedEncryptionEnforcementConfig(sameCsekConfig) + .build() + .update(); + + System.out.println("Encryption enforcement policy updated for bucket " + bucketName); + System.out.println("GMEK is now fully restricted, and CMEK enforcement has been removed."); + } + } +} +// [END storage_update_bucket_encryption_enforcement_config] diff --git a/samples/snippets/src/test/java/com/example/storage/ITBucketSnippets.java b/samples/snippets/src/test/java/com/example/storage/ITBucketSnippets.java index 6d649ef965..4fdd5e1fcc 100644 --- a/samples/snippets/src/test/java/com/example/storage/ITBucketSnippets.java +++ b/samples/snippets/src/test/java/com/example/storage/ITBucketSnippets.java @@ -46,6 +46,7 @@ import com.example.storage.bucket.EnableLifecycleManagement; import com.example.storage.bucket.EnableRequesterPays; import com.example.storage.bucket.EnableUniformBucketLevelAccess; +import com.example.storage.bucket.GetBucketEncryptionEnforcementConfig; import com.example.storage.bucket.GetBucketMetadata; import com.example.storage.bucket.GetBucketRpo; import com.example.storage.bucket.GetDefaultEventBasedHold; @@ -64,6 +65,7 @@ import com.example.storage.bucket.RemoveRetentionPolicy; import com.example.storage.bucket.SetAsyncTurboRpo; import com.example.storage.bucket.SetBucketDefaultKmsKey; +import com.example.storage.bucket.SetBucketEncryptionEnforcementConfig; import com.example.storage.bucket.SetBucketWebsiteInfo; import com.example.storage.bucket.SetClientEndpoint; import com.example.storage.bucket.SetDefaultRpo; @@ -71,6 +73,7 @@ import com.example.storage.bucket.SetPublicAccessPreventionInherited; import com.example.storage.bucket.SetRetentionPolicy; import com.example.storage.bucket.SetSoftDeletePolicy; +import com.example.storage.bucket.UpdateBucketEncryptionEnforcementConfig; import com.example.storage.object.DownloadRequesterPaysObject; import com.example.storage.object.ReleaseEventBasedHold; import com.example.storage.object.ReleaseTemporaryHold; @@ -83,6 +86,9 @@ import com.google.cloud.storage.BlobInfo; import com.google.cloud.storage.Bucket; import com.google.cloud.storage.BucketInfo; +import com.google.cloud.storage.BucketInfo.CustomerManagedEncryptionEnforcementConfig; +import com.google.cloud.storage.BucketInfo.EncryptionEnforcementRestrictionMode; +import com.google.cloud.storage.BucketInfo.GoogleManagedEncryptionEnforcementConfig; import com.google.cloud.storage.BucketInfo.PublicAccessPrevention; import com.google.cloud.storage.Cors; import com.google.cloud.storage.HttpMethod; @@ -712,4 +718,121 @@ public void testDisableSoftDelete() { storage.delete(tempBucket); } } + + @Test + public void testSetEncryptionEnforcementConfig() throws Throwable { + String gmekOnly = "g-" + BUCKET; + String cmekOnly = "c-" + BUCKET; + String restrictCsek = "rc-" + BUCKET; + + try { + SetBucketEncryptionEnforcementConfig.setBucketEncryptionEnforcementConfig(PROJECT_ID, BUCKET); + + TestUtils.retryAssert( + RETRY_SETTINGS, + () -> { + // Case 1: GMEK Only + Bucket b1 = storage.get(gmekOnly); + assertNotNull(b1); + assertEquals( + EncryptionEnforcementRestrictionMode.NOT_RESTRICTED, + b1.getGoogleManagedEncryptionEnforcementConfig().getRestrictionMode()); + assertEquals( + EncryptionEnforcementRestrictionMode.FULLY_RESTRICTED, + b1.getCustomerManagedEncryptionEnforcementConfig().getRestrictionMode()); + + // Case 2: CMEK Only + Bucket b2 = storage.get(cmekOnly); + assertNotNull(b2); + assertEquals( + EncryptionEnforcementRestrictionMode.FULLY_RESTRICTED, + b2.getGoogleManagedEncryptionEnforcementConfig().getRestrictionMode()); + assertEquals( + EncryptionEnforcementRestrictionMode.NOT_RESTRICTED, + b2.getCustomerManagedEncryptionEnforcementConfig().getRestrictionMode()); + + // Case 3: Restrict CSEK + Bucket b3 = storage.get(restrictCsek); + assertNotNull(b3); + assertEquals( + EncryptionEnforcementRestrictionMode.FULLY_RESTRICTED, + b3.getCustomerSuppliedEncryptionEnforcementConfig().getRestrictionMode()); + }); + } finally { + // Cleanup all three buckets + storage.delete(gmekOnly); + storage.delete(cmekOnly); + storage.delete(restrictCsek); + } + } + + @Test + public void testGetEncryptionEnforcementConfig() throws Throwable { + // Setup: Set a specific config to verify retrieval + GoogleManagedEncryptionEnforcementConfig gmekConfig = + GoogleManagedEncryptionEnforcementConfig.of( + EncryptionEnforcementRestrictionMode.FULLY_RESTRICTED); + BucketInfo bucketInfo = + storage.get(BUCKET).toBuilder() + .setGoogleManagedEncryptionEnforcementConfig(gmekConfig) + .build(); + storage.update(bucketInfo); + + TestUtils.retryAssert( + RETRY_SETTINGS, + () -> { + try { + GetBucketEncryptionEnforcementConfig.getBucketEncryptionEnforcementConfig( + PROJECT_ID, BUCKET); + String snippetOutput = stdOutCaptureRule.getCapturedOutputAsUtf8String(); + assertTrue(snippetOutput.contains("GMEK Enforcement: Mode: FullyRestricted")); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } + + @Test + public void testUpdateEncryptionEnforcementConfig() throws Throwable { + String tempBucketName = RemoteStorageHelper.generateBucketName(); + // Setup: Create the bucket with initial enforcement configs + BucketInfo initialInfo = + BucketInfo.newBuilder(tempBucketName) + .setCustomerManagedEncryptionEnforcementConfig( + CustomerManagedEncryptionEnforcementConfig.of( + EncryptionEnforcementRestrictionMode.FULLY_RESTRICTED)) + .setGoogleManagedEncryptionEnforcementConfig( + GoogleManagedEncryptionEnforcementConfig.of( + EncryptionEnforcementRestrictionMode.NOT_RESTRICTED)) + .build(); + + storage.create(initialInfo); + + try { + // Execution: Call the update snippet + // This snippet should update GMEK to FULLY_RESTRICTED and reset CMEK + UpdateBucketEncryptionEnforcementConfig.updateBucketEncryptionEnforcementConfig( + PROJECT_ID, tempBucketName); + + TestUtils.retryAssert( + RETRY_SETTINGS, + () -> { + Bucket bucket = storage.get(tempBucketName); + assertNotNull(bucket); + + // Verify GMEK was updated to FULLY_RESTRICTED + assertEquals( + EncryptionEnforcementRestrictionMode.FULLY_RESTRICTED, + bucket.getGoogleManagedEncryptionEnforcementConfig().getRestrictionMode()); + + // Verify CMEK was reverted/reset (defaults back to NOT_RESTRICTED) + assertEquals( + EncryptionEnforcementRestrictionMode.NOT_RESTRICTED, + bucket.getCustomerManagedEncryptionEnforcementConfig().getRestrictionMode()); + }); + + } finally { + storage.delete(tempBucketName); + } + } }