Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,4 @@
_(bucket.default_kms_key).must_be :nil?
end
end
end
end
115 changes: 115 additions & 0 deletions google-cloud-storage/lib/google/cloud/storage/bucket.rb
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,121 @@ def default_kms_key= new_default_kms_key
patch_gapi! :encryption
end

# The bucket's encryption configuration for customer-managed encryption keys.
# This configuration defines the
# default encryption behavior for the bucket and its files, and it can be used to enforce encryption requirements for the bucket.
# For more information, see [Bucket encryption](https://docs.cloud.google.com/storage/docs/encryption/).
# @return [Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig, nil] The bucket's encryption configuration, or `nil` if no encryption configuration has been set.
# @example
# require "google/cloud/storage"
# #
# storage = Google::Cloud::Storage.new
# bucket = storage.bucket "my-bucket"
# bucket.customer_managed_encryption_enforcement_config #=> Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig.new
# restriction_mode: "NotRestricted"
# The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted"

def customer_managed_encryption_enforcement_config
@gapi.encryption&.customer_managed_encryption_enforcement_config
end

# Sets the bucket's encryption configuration for customer-managed encryption that will be used to protect files.
# @param [Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig, nil] new_customer_managed_encryption_enforcement_config The bucket's encryption configuration, or `nil` to delete the encryption configuration.
# @example
# require "google/cloud/storage"
# #
# storage = Google::Cloud::Storage.new
# bucket = storage.bucket "my-bucket"
# new_config = Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig.new restriction_mode: "FullyRestricted"
# bucket.customer_managed_encryption_enforcement_config = new_config
# The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted"

def customer_managed_encryption_enforcement_config= new_customer_managed_encryption_enforcement_config
@gapi.encryption ||= API::Bucket::Encryption.new
@gapi.encryption.customer_managed_encryption_enforcement_config =
new_customer_managed_encryption_enforcement_config
patch_gapi! :encryption
end

##
# The bucket's encryption configuration for customer-supplied encryption keys. This configuration defines the
# default encryption behavior for the bucket and its files, and it can be used to enforce encryption requirements
# for the bucket.
# For more information, see [Bucket encryption](https://docs.cloud.google.com/storage/docs/encryption/).
# @return [Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig, nil]
# The bucket's encryption configuration, or `nil` if no encryption configuration has been set.
# @example
# require "google/cloud/storage"
# #
# storage = Google::Cloud::Storage.new
# bucket = storage.bucket "my-bucket"
# bucket.customer_supplied_encryption_enforcement_config #=> Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig.new
# restriction_mode: "NotRestricted"
# The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted".

def customer_supplied_encryption_enforcement_config
@gapi.encryption&.customer_supplied_encryption_enforcement_config
end

##
# Sets the bucket's encryption configuration for customer-managed encryption that will be used to protect files.
# @param [Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig, nil] new_customer_supplied_encryption_enforcement_config The bucket's encryption configuration, or `nil` to delete the encryption configuration.
# @example
# require "google/cloud/storage"
# #
# storage = Google::Cloud::Storage.new
# bucket = storage.bucket "my-bucket"
# new_config = Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig.new restriction_mode: "FullyRestricted"
# bucket.customer_supplied_encryption_enforcement_config = new_config
# The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted"

def customer_supplied_encryption_enforcement_config= new_customer_supplied_encryption_enforcement_config
@gapi.encryption ||= API::Bucket::Encryption.new
@gapi.encryption.customer_supplied_encryption_enforcement_config =
new_customer_supplied_encryption_enforcement_config
patch_gapi! :encryption
end

##
# The bucket's encryption configuration for google-managed encryption keys.
# This configuration defines the
# default encryption behavior for the bucket and its files, and it can be used to enforce encryption
# requirements for the bucket.
# For more information, see [Bucket encryption](https://docs.cloud.google.com/storage/docs/encryption/).
# @return [Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig, nil]
# The bucket's encryption configuration, or `nil` if no encryption configuration has been set.
# @example
# require "google/cloud/storage"
# #
# storage = Google::Cloud::Storage.new
# bucket = storage.bucket "my-bucket"
# bucket.google_managed_encryption_enforcement_config #=> Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new
# restriction_mode: "NotRestricted"
# The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted".

def google_managed_encryption_enforcement_config
@gapi.encryption&.google_managed_encryption_enforcement_config
end

##
# Sets the bucket's encryption configuration for google-managed encryption that will be used to protect files.
# @param [Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig, nil] new_google_managed_encryption_enforcement_config The bucket's encryption configuration, or `nil` to delete the encryption configuration.
# @example
# require "google/cloud/storage"
# #
# storage = Google::Cloud::Storage.new
# bucket = storage.bucket "my-bucket"
# new_config = Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig.new restriction_mode: "FullyRestricted"
# bucket.google_managed_encryption_enforcement_config = new_config
# The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted"

def google_managed_encryption_enforcement_config= new_google_managed_encryption_enforcement_config
@gapi.encryption ||= API::Bucket::Encryption.new
@gapi.encryption.google_managed_encryption_enforcement_config =
new_google_managed_encryption_enforcement_config
patch_gapi! :encryption
end

##
# The period of time (in seconds) that files in the bucket must be
# retained, and cannot be deleted, overwritten, or archived.
Expand Down
41 changes: 41 additions & 0 deletions google-cloud-storage/samples/acceptance/buckets_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
require_relative "../storage_get_bucket_class_and_location"
require_relative "../storage_get_bucket_metadata"
require_relative "../storage_get_default_event_based_hold"
require_relative "../storage_get_encryption_enforcement_config"
require_relative "../storage_get_public_access_prevention"
require_relative "../storage_get_requester_pays_status"
require_relative "../storage_get_retention_policy"
Expand All @@ -48,6 +49,8 @@
require_relative "../storage_remove_cors_configuration"
require_relative "../storage_remove_retention_policy"
require_relative "../storage_set_bucket_default_kms_key"
require_relative "../storage_set_encryption_enforcement_config"
require_relative "../storage_remove_all_encryption_enforcement_config"
require_relative "../storage_set_object_retention_policy"
require_relative "../storage_set_public_access_prevention_enforced"
require_relative "../storage_set_public_access_prevention_inherited"
Expand Down Expand Up @@ -169,6 +172,44 @@
end
end

describe "storage_encryption_enforcement_config" do
bucket_name = random_bucket_name

it "gets, sets and clears bucket encryption enforcement config" do
# creates bucket with encryption enforcement config
expected = "Created bucket #{bucket_name} with Encryption Enforcement Config.\n"

retry_resource_exhaustion do
assert_output expected do
set_encryption_enforcement_config bucket_name: bucket_name
end
end

# get encryption enforcement config
expected = "Encryption Enforcement Config for bucket #{bucket_name}:\n" \
"Customer-managed encryption enforcement config restriction mode: NotRestricted\n" \
"Customer-supplied encryption enforcement config restriction mode: FullyRestricted\n" \
"Google-managed encryption enforcement config restriction mode: FullyRestricted\n"
retry_resource_exhaustion do
assert_output expected do
get_encryption_enforcement_config bucket_name: bucket_name
end
end

# clears encryption enforcement config
expected = "Removed Encryption Enforcement Config from bucket #{bucket_name}.\n"

retry_resource_exhaustion do
assert_output expected do
remove_all_encryption_enforcement_config bucket_name: bucket_name
end
end

refute_nil storage_client.bucket bucket_name
end
delete_bucket_helper bucket_name
end

describe "storage_create_bucket_with_object_retention" do
it "creates a bucket with object retention enabled." do
bucket_name = random_bucket_name
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# 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]
def get_encryption_enforcement_config bucket_name:
# The ID to give your GCS bucket
# bucket_name = "your-unique-bucket-name"

require "google/cloud/storage"

storage = Google::Cloud::Storage.new
bucket = storage.bucket bucket_name
puts "Encryption Enforcement Config for bucket #{bucket.name}:"
puts "Customer-managed encryption enforcement config restriction mode: " \
"#{bucket.customer_managed_encryption_enforcement_config&.restriction_mode}"
puts "Customer-supplied encryption enforcement config restriction mode: " \
"#{bucket.customer_supplied_encryption_enforcement_config&.restriction_mode}"
puts "Google-managed encryption enforcement config restriction mode: " \
"#{bucket.google_managed_encryption_enforcement_config&.restriction_mode}"
end
# [END storage_get_encryption_enforcement_config]

if $PROGRAM_NAME == __FILE__
get_encryption_enforcement_config bucket_name: ARGV.shift
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# 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]
def remove_all_encryption_enforcement_config bucket_name:
# The ID to give your GCS bucket
# bucket_name = "your-unique-bucket-name"

require "google/cloud/storage"

storage = Google::Cloud::Storage.new
bucket = storage.bucket bucket_name do |b|
b.customer_managed_encryption_enforcement_config = nil
b.customer_supplied_encryption_enforcement_config = nil
b.google_managed_encryption_enforcement_config = nil
end
puts "Removed Encryption Enforcement Config from bucket #{bucket.name}."
end
# [END storage_remove_all_encryption_enforcement_config]

if $PROGRAM_NAME == __FILE__
remove_all_encryption_enforcement_config bucket_name: ARGV.shift
end
Original file line number Diff line number Diff line change
@@ -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_set_encryption_enforcement_config]
def set_encryption_enforcement_config bucket_name:
# The ID to give your GCS bucket
# bucket_name = "your-unique-bucket-name"

require "google/cloud/storage"

storage = Google::Cloud::Storage.new

customer_managed_config =
Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig.new(
restriction_mode: "NotRestricted"
)
customer_supplied_config =
Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig.new(
restriction_mode: "FullyRestricted"
)
google_managed_config =
Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new(
restriction_mode: "FullyRestricted"
)

bucket = storage.create_bucket bucket_name do |b|
b.customer_managed_encryption_enforcement_config = customer_managed_config
b.customer_supplied_encryption_enforcement_config = customer_supplied_config
b.google_managed_encryption_enforcement_config = google_managed_config
end
puts "Created bucket #{bucket.name} with Encryption Enforcement Config."
end
# [END storage_set_encryption_enforcement_config]

if $PROGRAM_NAME == __FILE__
set_encryption_enforcement_config bucket_name: ARGV.shift
end
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
let(:bucket_json) { bucket_hash.to_json }
let(:bucket_gapi) { Google::Apis::StorageV1::Bucket.from_json bucket_json }
let(:bucket) { Google::Cloud::Storage::Bucket.from_gapi bucket_gapi, storage.service }
let(:kms_key) { "path/to/encryption_key_name" }


describe "customer-supplied encryption key (CSEK)" do
let(:encryption_key) { "y\x03\"\x0E\xB6\xD3\x9B\x0E\xAB*\x19\xFAv\xDEY\xBEI\xF8ftA|[z\x1A\xFBE\xDE\x97&\xBC\xC7" }
Expand Down Expand Up @@ -70,11 +72,9 @@
end

describe "KMS customer-managed encryption key (CMEK)" do
let(:kms_key) { "path/to/encryption_key_name" }

it "gets and sets its encryption config" do
mock = Minitest::Mock.new
patch_bucket_gapi = Google::Apis::StorageV1::Bucket.new encryption: encryption_gapi(kms_key)
patch_bucket_gapi = Google::Apis::StorageV1::Bucket.new encryption: encryption_gapi(key_name: kms_key)
mock.expect :patch_bucket, patch_bucket_gapi, [bucket_name, patch_bucket_gapi], **patch_bucket_args(options: {retries: 0})

bucket.service.mocked_service = mock
Expand All @@ -88,11 +88,12 @@

it "sets its encryption config to nil" do
bucket_gapi_with_key = bucket_gapi.dup
bucket_gapi_with_key.encryption = encryption_gapi(kms_key)
bucket_gapi_with_key.encryption = encryption_gapi(key_name: kms_key)
bucket_with_key = Google::Cloud::Storage::Bucket.from_gapi bucket_gapi_with_key, storage.service
patch_bucket_gapi = Google::Apis::StorageV1::Bucket.new encryption: encryption_gapi(nil)
mock = Minitest::Mock.new
mock.expect :patch_bucket, bucket_gapi, [bucket_name, patch_bucket_gapi], **patch_bucket_args(options: {retries: 0})
mock.expect :patch_bucket, bucket_gapi do |name, patch_obj, **args|
name == bucket_name && patch_obj.encryption&.default_kms_key_name.nil?
end

bucket_with_key.service.mocked_service = mock

Expand Down Expand Up @@ -122,7 +123,6 @@
end
end


def create_file_gapi bucket=nil, name = nil
Google::Apis::StorageV1::Object.from_json random_file_hash(bucket, name).to_json
end
Expand Down
Loading
Loading