Skip to content
This repository was archived by the owner on Mar 31, 2026. It is now read-only.

Commit 7ce8493

Browse files
samples: add samples for bucket encryption enforcement config (#1772)
Add Python samples demonstrating how to set, get and update bucket encryption enforcement configuration. Includes an integration test. --- *PR created automatically by Jules for task [3410657303470871774](https://jules.google.com/task/3410657303470871774) started by @nidhiii-27* --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: nidhiii-27 <224584462+nidhiii-27@users.noreply.github.com>
1 parent b221c8e commit 7ce8493

File tree

4 files changed

+271
-5
lines changed

4 files changed

+271
-5
lines changed

samples/snippets/encryption_test.py

Lines changed: 108 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
import storage_object_csek_to_cmek
2828
import storage_rotate_encryption_key
2929
import storage_upload_encrypted_file
30+
import storage_get_bucket_encryption_enforcement_config
31+
import storage_set_bucket_encryption_enforcement_config
32+
import storage_update_bucket_encryption_enforcement_config
33+
from google.cloud.storage.bucket import EncryptionEnforcementConfig
3034

3135
BUCKET = os.environ["CLOUD_STORAGE_BUCKET"]
3236
KMS_KEY = os.environ["MAIN_CLOUD_KMS_KEY"]
@@ -85,11 +89,7 @@ def test_blob():
8589
except NotFound as e:
8690
# For the case that the rotation succeeded.
8791
print(f"Ignoring 404, detail: {e}")
88-
blob = Blob(
89-
blob_name,
90-
bucket,
91-
encryption_key=TEST_ENCRYPTION_KEY_2_DECODED
92-
)
92+
blob = Blob(blob_name, bucket, encryption_key=TEST_ENCRYPTION_KEY_2_DECODED)
9393
blob.delete()
9494

9595

@@ -126,3 +126,106 @@ def test_object_csek_to_cmek(test_blob):
126126
)
127127

128128
assert cmek_blob.download_as_bytes(), test_blob_content
129+
130+
131+
@pytest.fixture
132+
def enforcement_bucket():
133+
bucket_name = f"test_encryption_enforcement_{uuid.uuid4().hex}"
134+
yield bucket_name
135+
136+
storage_client = storage.Client()
137+
try:
138+
bucket = storage_client.get_bucket(bucket_name)
139+
bucket.delete(force=True)
140+
except Exception:
141+
pass
142+
143+
144+
def create_enforcement_bucket(bucket_name):
145+
"""Sets up a bucket with GMEK AND CSEK Restricted"""
146+
client = storage.Client()
147+
bucket = client.bucket(bucket_name)
148+
149+
bucket.encryption.google_managed_encryption_enforcement_config = (
150+
EncryptionEnforcementConfig(restriction_mode="FullyRestricted")
151+
)
152+
bucket.encryption.customer_managed_encryption_enforcement_config = (
153+
EncryptionEnforcementConfig(restriction_mode="NotRestricted")
154+
)
155+
bucket.encryption.customer_supplied_encryption_enforcement_config = (
156+
EncryptionEnforcementConfig(restriction_mode="FullyRestricted")
157+
)
158+
159+
bucket.create()
160+
return bucket
161+
162+
163+
def test_set_bucket_encryption_enforcement_config(enforcement_bucket):
164+
storage_set_bucket_encryption_enforcement_config.set_bucket_encryption_enforcement_config(
165+
enforcement_bucket
166+
)
167+
168+
storage_client = storage.Client()
169+
bucket = storage_client.get_bucket(enforcement_bucket)
170+
171+
assert (
172+
bucket.encryption.google_managed_encryption_enforcement_config.restriction_mode
173+
== "FullyRestricted"
174+
)
175+
assert (
176+
bucket.encryption.customer_managed_encryption_enforcement_config.restriction_mode
177+
== "NotRestricted"
178+
)
179+
assert (
180+
bucket.encryption.customer_supplied_encryption_enforcement_config.restriction_mode
181+
== "FullyRestricted"
182+
)
183+
184+
185+
def test_get_bucket_encryption_enforcement_config(enforcement_bucket, capsys):
186+
# Pre-setup: Creating a bucket
187+
create_enforcement_bucket(enforcement_bucket)
188+
189+
storage_get_bucket_encryption_enforcement_config.get_bucket_encryption_enforcement_config(
190+
enforcement_bucket
191+
)
192+
193+
out, _ = capsys.readouterr()
194+
assert f"Encryption Enforcement Config for bucket {enforcement_bucket}" in out
195+
assert (
196+
"Customer-managed encryption enforcement config restriction mode: NotRestricted"
197+
in out
198+
)
199+
assert (
200+
"Customer-supplied encryption enforcement config restriction mode: FullyRestricted"
201+
in out
202+
)
203+
assert (
204+
"Google-managed encryption enforcement config restriction mode: FullyRestricted"
205+
in out
206+
)
207+
208+
209+
def test_update_encryption_enforcement_config(enforcement_bucket):
210+
# Pre-setup: Create a bucket in a different state before update
211+
create_enforcement_bucket(enforcement_bucket)
212+
213+
storage_update_bucket_encryption_enforcement_config.update_bucket_encryption_enforcement_config(
214+
enforcement_bucket
215+
)
216+
217+
storage_client = storage.Client()
218+
bucket = storage_client.get_bucket(enforcement_bucket)
219+
220+
assert (
221+
bucket.encryption.google_managed_encryption_enforcement_config.restriction_mode
222+
== "NotRestricted"
223+
)
224+
assert (
225+
bucket.encryption.customer_managed_encryption_enforcement_config.restriction_mode
226+
== "FullyRestricted"
227+
)
228+
assert (
229+
bucket.encryption.customer_supplied_encryption_enforcement_config.restriction_mode
230+
== "FullyRestricted"
231+
)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# [START storage_get_bucket_encryption_enforcement_config]
16+
from google.cloud import storage
17+
18+
19+
def get_bucket_encryption_enforcement_config(bucket_name):
20+
"""Gets the bucket encryption enforcement configuration."""
21+
# The ID of your GCS bucket
22+
# bucket_name = "your-unique-bucket-name"
23+
24+
storage_client = storage.Client()
25+
bucket = storage_client.get_bucket(bucket_name)
26+
27+
print(f"Encryption Enforcement Config for bucket {bucket.name}:")
28+
29+
cmek_config = bucket.encryption.customer_managed_encryption_enforcement_config
30+
csek_config = bucket.encryption.customer_supplied_encryption_enforcement_config
31+
gmek_config = bucket.encryption.google_managed_encryption_enforcement_config
32+
33+
print(
34+
f"Customer-managed encryption enforcement config restriction mode: {cmek_config.restriction_mode if cmek_config else None}"
35+
)
36+
print(
37+
f"Customer-supplied encryption enforcement config restriction mode: {csek_config.restriction_mode if csek_config else None}"
38+
)
39+
print(
40+
f"Google-managed encryption enforcement config restriction mode: {gmek_config.restriction_mode if gmek_config else None}"
41+
)
42+
43+
44+
# [END storage_get_bucket_encryption_enforcement_config]
45+
46+
47+
if __name__ == "__main__":
48+
get_bucket_encryption_enforcement_config(bucket_name="your-unique-bucket-name")
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# [START storage_set_bucket_encryption_enforcement_config]
16+
from google.cloud import storage
17+
from google.cloud.storage.bucket import EncryptionEnforcementConfig
18+
19+
20+
def set_bucket_encryption_enforcement_config(bucket_name):
21+
"""Creates a bucket with encryption enforcement configuration."""
22+
# The ID of your GCS bucket
23+
# bucket_name = "your-unique-bucket-name"
24+
25+
storage_client = storage.Client()
26+
bucket = storage_client.bucket(bucket_name)
27+
28+
# Setting restriction_mode to "FullyRestricted" for Google-managed encryption (GMEK)
29+
# means objects cannot be created using the default Google-managed keys.
30+
bucket.encryption.google_managed_encryption_enforcement_config = (
31+
EncryptionEnforcementConfig(restriction_mode="FullyRestricted")
32+
)
33+
34+
# Setting restriction_mode to "NotRestricted" for Customer-managed encryption (CMEK)
35+
# ensures that objects ARE permitted to be created using Cloud KMS keys.
36+
bucket.encryption.customer_managed_encryption_enforcement_config = (
37+
EncryptionEnforcementConfig(restriction_mode="NotRestricted")
38+
)
39+
40+
# Setting restriction_mode to "FullyRestricted" for Customer-supplied encryption (CSEK)
41+
# prevents objects from being created using raw, client-side provided keys.
42+
bucket.encryption.customer_supplied_encryption_enforcement_config = (
43+
EncryptionEnforcementConfig(restriction_mode="FullyRestricted")
44+
)
45+
46+
bucket.create()
47+
48+
print(f"Created bucket {bucket.name} with Encryption Enforcement Config.")
49+
50+
51+
# [END storage_set_bucket_encryption_enforcement_config]
52+
53+
54+
if __name__ == "__main__":
55+
set_bucket_encryption_enforcement_config(bucket_name="your-unique-bucket-name")
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# [START storage_update_bucket_encryption_enforcement_config]
16+
from google.cloud import storage
17+
from google.cloud.storage.bucket import EncryptionEnforcementConfig
18+
19+
20+
def update_bucket_encryption_enforcement_config(bucket_name):
21+
"""Updates the encryption enforcement policy for a bucket."""
22+
# The ID of your GCS bucket with GMEK and CSEK restricted
23+
# bucket_name = "your-unique-bucket-name"
24+
25+
storage_client = storage.Client()
26+
bucket = storage_client.get_bucket(bucket_name)
27+
28+
# Update a specific type (e.g., change GMEK to NotRestricted)
29+
bucket.encryption.google_managed_encryption_enforcement_config = (
30+
EncryptionEnforcementConfig(restriction_mode="NotRestricted")
31+
)
32+
33+
# Update another type (e.g., change CMEK to FullyRestricted)
34+
bucket.encryption.customer_managed_encryption_enforcement_config = (
35+
EncryptionEnforcementConfig(restriction_mode="FullyRestricted")
36+
)
37+
38+
# Keeping CSEK unchanged
39+
bucket.encryption.customer_supplied_encryption_enforcement_config = (
40+
EncryptionEnforcementConfig(restriction_mode="FullyRestricted")
41+
)
42+
43+
bucket.patch()
44+
45+
print(f"Encryption enforcement policy updated for bucket {bucket.name}.")
46+
47+
gmek = bucket.encryption.google_managed_encryption_enforcement_config
48+
cmek = bucket.encryption.customer_managed_encryption_enforcement_config
49+
csek = bucket.encryption.customer_supplied_encryption_enforcement_config
50+
51+
print(f"GMEK restriction mode: {gmek.restriction_mode if gmek else 'None'}")
52+
print(f"CMEK restriction mode: {cmek.restriction_mode if cmek else 'None'}")
53+
print(f"CSEK restriction mode: {csek.restriction_mode if csek else 'None'}")
54+
55+
56+
# [END storage_update_bucket_encryption_enforcement_config]
57+
58+
59+
if __name__ == "__main__":
60+
update_bucket_encryption_enforcement_config(bucket_name="your-unique-bucket-name")

0 commit comments

Comments
 (0)