Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
598851a
adding ostruct gem in samples
shubhangi-google Mar 25, 2026
53ee419
adding functionality
shubhangi-google Mar 3, 2026
be44e07
Add newline at end of bucket_encryption_test.rb
shubhangi-google Mar 3, 2026
96e3fa2
renaming tags
shubhangi-google Mar 16, 2026
3658979
adding update functionality
shubhangi-google Mar 25, 2026
221d38b
adding tests
shubhangi-google Mar 29, 2026
a0ddae3
fixing rubocop issue
shubhangi-google Mar 29, 2026
87a5e37
removing unwanted code
shubhangi-google Mar 30, 2026
d01e6d1
updating update sample
shubhangi-google Mar 30, 2026
a21d625
update
shubhangi-google Mar 30, 2026
2d5b5e3
Remove unnecessary line in bucket encryption test
shubhangi-google Mar 30, 2026
67e25f9
fix
shubhangi-google Mar 30, 2026
69e6fd9
Remove blank line in bucket.rb
shubhangi-google Mar 30, 2026
f88d02e
Clean up comments in bucket.rb
shubhangi-google Mar 30, 2026
27632c6
Clean up comments in bucket.rb
shubhangi-google Mar 30, 2026
794c7cc
Clean up comments in bucket.rb
shubhangi-google Mar 30, 2026
d7a5cca
Remove unnecessary line in encryption config update
shubhangi-google Mar 31, 2026
36ea00e
blank commit
shubhangi-google Mar 31, 2026
88c4b82
updating tests
shubhangi-google Apr 2, 2026
0b76c34
updating doc
shubhangi-google Apr 6, 2026
e493d07
updating code
shubhangi-google Apr 7, 2026
b4e1f13
updating tests
shubhangi-google Apr 7, 2026
c816b92
added example
shubhangi-google Apr 8, 2026
13a50a9
fix indentation
shubhangi-google Apr 8, 2026
e7f1983
using update method
shubhangi-google Apr 14, 2026
1eef09d
remove pry
shubhangi-google Apr 14, 2026
0cb6b84
blank commit
shubhangi-google Apr 14, 2026
b293a4b
blank commit
shubhangi-google Apr 14, 2026
3fb0ccf
blank commit
shubhangi-google Apr 14, 2026
acf92dd
refactoring tests
shubhangi-google Apr 15, 2026
d4c65f7
blank commit
shubhangi-google Apr 15, 2026
22aafe8
adding ostruct gem in samples
shubhangi-google Mar 25, 2026
3b2dad5
Merge branch 'main' into support_bucket_encryption_config
shubhangi-google Apr 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,23 @@
ENV["GCLOUD_TEST_STORAGE_KMS_KEY_2"] ||
"projects/#{storage.project_id}/locations/#{bucket_location}/keyRings/ruby-test/cryptoKeys/ruby-test-key-2"
}

let(:customer_managed_config) do
{ restriction_mode: "NotRestricted" }
end

let(:customer_supplied_config) do
{ restriction_mode: "FullyRestricted" }
end

let(:google_managed_config) do
{ restriction_mode: "FullyRestricted" }
end

let :bucket do
b = safe_gcs_execute { storage.create_bucket(bucket_name, location: bucket_location) }
b = safe_gcs_execute { storage.bucket(bucket_name) || storage.create_bucket(bucket_name, location: bucket_location) }
b.default_kms_key = kms_key
b.customer_managed_encryption_enforcement_config = customer_managed_config
b
end

Expand Down Expand Up @@ -71,4 +85,45 @@
_(bucket.default_kms_key).must_be :nil?
end
end

describe "Encryption Enforcement Config" do
let(:google_managed_config_complete) do
{google_managed_encryption_enforcement_config: { restriction_mode: "FullyRestricted" } }
end
it "knows its encryption enforcement config" do
_(bucket.customer_managed_encryption_enforcement_config).wont_be :nil?
_(bucket.customer_managed_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted"
bucket.reload!
_(bucket.customer_managed_encryption_enforcement_config).wont_be :nil?
_(bucket.customer_managed_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted"
end

it "updates encryption enforcement configs" do
_(bucket.customer_supplied_encryption_enforcement_config).must_be :nil?

bucket.customer_supplied_encryption_enforcement_config = customer_supplied_config
_(bucket.customer_supplied_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted"
bucket.update do |b|
b.google_managed_encryption_enforcement_config = google_managed_config
end
_(bucket.google_managed_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted"

bucket.reload!
_(bucket.customer_supplied_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted"
_(bucket.google_managed_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted"
end

it "deletes all encryption enforcement configs" do
bucket.update do |b|
b.customer_managed_encryption_enforcement_config = nil
b.customer_supplied_encryption_enforcement_config = nil
b.google_managed_encryption_enforcement_config = nil
end
# Removed all encryption enforcement configs without removing default_kms_key
_(bucket.customer_managed_encryption_enforcement_config).must_be :nil?
_(bucket.customer_supplied_encryption_enforcement_config).must_be :nil?
_(bucket.google_managed_encryption_enforcement_config).must_be :nil?
_(bucket.default_kms_key).must_equal kms_key
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
let(:bucket_location) { "us-central1" }

let :bucket do
safe_gcs_execute {storage.create_bucket bucket_name, location: bucket_location }
safe_gcs_execute { storage.bucket(bucket_name) || storage.create_bucket(bucket_name, location: bucket_location) }
end

let(:file_path) { "acceptance/data/abc.txt" }
Expand Down
186 changes: 186 additions & 0 deletions google-cloud-storage/lib/google/cloud/storage/bucket.rb
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,171 @@ def default_kms_key= new_default_kms_key
default_kms_key_name: 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:0x00007f3b1c102e90 @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 customer-managed encryption enforcement configuration for the bucket.
#
# @param new_customer_managed_encryption_enforcement_config [Hash, nil]
# The configuration hash for encryption enforcement.
# * `:restriction_mode` (String) - Can be "NotRestricted" or "FullyRestricted".
# Pass `nil` to clear the current configuration.
#
# @example Enforcing Customer-Managed Encryption
# require "google/cloud/storage"
#
# storage = Google::Cloud::Storage.new
# bucket = storage.bucket "my-bucket"
#
# # Set restriction mode to FullyRestricted
# new_config = { restriction_mode: "FullyRestricted" }
Comment thread
bajajneha27 marked this conversation as resolved.
# bucket.customer_managed_encryption_enforcement_config = new_config
#
# @example Setting via Request Object (Google API Client)
# require "google/apis/storage_v1"
#
# enforcement_config = { restriction_mode: "FullyRestricted" }
#
# request_obj = Google::Apis::StorageV1::Bucket::Encryption.new(
# customer_managed_encryption_enforcement_config: enforcement_config
# )
# bucket.customer_managed_encryption_enforcement_config = request_obj
#
# @return [Hash, Google::Apis::StorageV1::Bucket::Encryption] The updated configuration.
# @raise [Google::Cloud::Error] If the update fails due to permissions or invalid arguments.
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.
# 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:0x00007f3b1c102e90 @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-supplied encryption that will be used to protect files.
# @param new_customer_supplied_encryption_enforcement_config [Hash, nil]
# The configuration hash for encryption enforcement.
# * `:restriction_mode` (String) - Can be "NotRestricted" or "FullyRestricted".
# Pass `nil` to clear the current configuration.
# @example
# require "google/cloud/storage"
#
# storage = Google::Cloud::Storage.new
# bucket = storage.bucket "my-bucket"
# new_config = { restriction_mode: "FullyRestricted" }
Comment thread
shubhangi-google marked this conversation as resolved.
# bucket.customer_supplied_encryption_enforcement_config = new_config
#
# @example Setting via Request Object (Google API Client)
# require "google/apis/storage_v1"
#
# enforcement_config = { restriction_mode: "FullyRestricted" }
#
# request_obj = Google::Apis::StorageV1::Bucket::Encryption.new(
# customer_supplied_encryption_enforcement_config: enforcement_config
# )
# bucket.customer_supplied_encryption_enforcement_config = request_obj
#
# @return [Hash, Google::Apis::StorageV1::Bucket::Encryption] The updated configuration.
# @raise [Google::Cloud::Error] If the update fails due to permissions or invalid arguments.

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:0x00007f3b1c102e90 @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 google-managed encryption enforcement configuration for the bucket.
#
# @param new_google_managed_encryption_enforcement_config [Hash, nil]
# The configuration hash for encryption enforcement.
# * `:restriction_mode` (String) - Can be "NotRestricted" or "FullyRestricted".
# Pass `nil` to clear the current configuration.
#
# @example Enforcing Customer-Managed Encryption
# require "google/cloud/storage"
#
# storage = Google::Cloud::Storage.new
# bucket = storage.bucket "my-bucket"
# # Set restriction mode to FullyRestricted
# new_config = { restriction_mode: "FullyRestricted" }
# bucket.new_google_managed_encryption_enforcement_config = new_config
#
# @example Setting via Request Object (Google API Client)
# require "google/apis/storage_v1"
#
# enforcement_config = { restriction_mode: "FullyRestricted" }
#
# request_obj = Google::Apis::StorageV1::Bucket::Encryption.new(
# google_managed_encryption_enforcement_config: enforcement_config
# )
# bucket.google_managed_encryption_enforcement_config = request_obj
#
# @return [Hash, Google::Apis::StorageV1::Bucket::Encryption] The updated configuration.
# @raise [Google::Cloud::Error] If the update fails due to permissions or invalid arguments.

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
Expand Down Expand Up @@ -1373,6 +1538,7 @@ def update if_metageneration_match: nil, if_metageneration_not_match: nil
updater.check_for_changed_labels!
updater.check_for_mutable_cors!
updater.check_for_mutable_lifecycle!
updater.check_for_encryption_enforcement_config!
return if updater.updates.empty?
update_gapi! updater.updates,
if_metageneration_match: if_metageneration_match,
Expand Down Expand Up @@ -3386,6 +3552,26 @@ def check_for_mutable_lifecycle!
patch_gapi! :lifecycle
end

def check_for_encryption_enforcement_config!
return unless @gapi.encryption

[
:google_managed_encryption_enforcement_config,
:customer_managed_encryption_enforcement_config,
:customer_supplied_encryption_enforcement_config
].each do |attr|
config = @gapi.encryption.send(attr)
next unless config
unless config.respond_to?(:to_h)
raise ArgumentError, "Encryption config for #{attr} must be a Hash or valid Config object"
end
clean_config = config.to_h
clean_config.delete :effective_time
clean_config.delete "effective_time"
Comment thread
bajajneha27 marked this conversation as resolved.
@gapi.encryption.send "#{attr}=", clean_config
end
end

protected

##
Expand Down
4 changes: 4 additions & 0 deletions google-cloud-storage/samples/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,7 @@ group :test do
gem "minitest-hooks", "~> 1.5"
gem "rake"
end
# The following gems have been removed from ruby core and are required for testing.
gem "ostruct"
Comment thread
bajajneha27 marked this conversation as resolved.
gem "cgi"
gem "irb"
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,17 +37,20 @@
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_bucket_encryption_enforcement_config"
require_relative "../storage_get_public_access_prevention"
require_relative "../storage_get_requester_pays_status"
require_relative "../storage_get_retention_policy"
require_relative "../storage_get_uniform_bucket_level_access"
require_relative "../storage_list_buckets"
require_relative "../storage_list_buckets_with_partial_success"
require_relative "../storage_lock_retention_policy"
require_relative "../storage_update_bucket_encryption_enforcement_config"
require_relative "../storage_remove_bucket_label"
require_relative "../storage_remove_cors_configuration"
require_relative "../storage_remove_retention_policy"
require_relative "../storage_set_bucket_default_kms_key"
require_relative "../storage_set_bucket_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_bucket_encryption_enforcement_config" do
bucket_name = random_bucket_name

it "gets, sets and updates 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_bucket_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_bucket_encryption_enforcement_config bucket_name: bucket_name
end
end

# update encryption enforcement config
expected = "Updated google_managed_config to NotRestricted for bucket #{bucket_name}.\n"

retry_resource_exhaustion do
assert_output expected do
update_bucket_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_bucket_encryption_enforcement_config]
def get_bucket_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_bucket_encryption_enforcement_config]

if $PROGRAM_NAME == __FILE__
get_bucket_encryption_enforcement_config bucket_name: ARGV.shift
end
Loading
Loading