Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
52 changes: 52 additions & 0 deletions kms/snippets/delete_key.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# 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 kms_delete_key]
from google.cloud import kms


def delete_key(
project_id: str, location_id: str, key_ring_id: str, key_id: str
) -> None:
"""
Delete the given key.

Args:
project_id (str): Google Cloud project ID (e.g. 'my-project').
location_id (str): Cloud KMS location (e.g. 'us-east1').
key_ring_id (str): ID of the Cloud KMS key ring (e.g. 'my-key-ring').
key_id (str): ID of the key to use (e.g. 'my-key').

Returns:
None

"""

# Create the client.
client = kms.KeyManagementServiceClient()

# Build the key name.
key_name = client.crypto_key_path(project_id, location_id, key_ring_id, key_id)

# Call the API.
# Note: delete_crypto_key returns a long-running operation.
operation = client.delete_crypto_key(request={"name": key_name})

# Wait for the operation to complete.
operation.result()

print(f"Deleted key: {key_name}")


# [END kms_delete_key]
55 changes: 55 additions & 0 deletions kms/snippets/delete_key_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# 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 kms_delete_key_version]
from google.cloud import kms


def delete_key_version(
project_id: str, location_id: str, key_ring_id: str, key_id: str, version_id: str
) -> None:
"""
Delete the given key version.

Args:
project_id (str): Google Cloud project ID (e.g. 'my-project').
location_id (str): Cloud KMS location (e.g. 'us-east1').
key_ring_id (str): ID of the Cloud KMS key ring (e.g. 'my-key-ring').
key_id (str): ID of the key to use (e.g. 'my-key').
version_id (str): ID of the key version to delete (e.g. '1').

Returns:
None

"""

# Create the client.
client = kms.KeyManagementServiceClient()

# Build the key version name.
key_version_name = client.crypto_key_version_path(
project_id, location_id, key_ring_id, key_id, version_id
)

# Call the API.
# Note: delete_crypto_key_version returns a long-running operation.
operation = client.delete_crypto_key_version(request={"name": key_version_name})

# Wait for the operation to complete.
operation.result()

print(f"Deleted key version: {key_version_name}")


# [END kms_delete_key_version]
50 changes: 50 additions & 0 deletions kms/snippets/get_retired_resource.py
Original file line number Diff line number Diff line change
@@ -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.

# [START kms_get_retired_resource]
from google.cloud import kms


def get_retired_resource(
project_id: str, location_id: str, retired_resource_id: str
) -> kms.RetiredResource:
"""
Get the details of a retired resource.

Args:
project_id (str): Google Cloud project ID (e.g. 'my-project').
location_id (str): Cloud KMS location (e.g. 'us-east1').
resource_id (str): ID of the retired resource to get.

Returns:
kms.RetiredResource: The requested retired resource.

"""

# Create the client.
client = kms.KeyManagementServiceClient()

# Build the retired resource name.
# Note: Retired resources are tied to a Location, not a KeyRing.
# The name is like projects/{project}/locations/{location}/retiredResources/{id}
name = client.retired_resource_path(project_id, location_id, retired_resource_id)

# Call the API.
response = client.get_retired_resource(request={"name": name})

print(f"Got retired resource: {response.name}")
return response


# [END kms_get_retired_resource]
50 changes: 50 additions & 0 deletions kms/snippets/list_retired_resources.py
Original file line number Diff line number Diff line change
@@ -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.

# [START kms_list_retired_resources]
from typing import List

from google.cloud import kms


def list_retired_resources(project_id: str, location_id: str) -> List[kms.RetiredResource]:
"""
List the retired resources in a location.

Args:
project_id (str): Google Cloud project ID (e.g. 'my-project').
location_id (str): Cloud KMS location (e.g. 'us-east1').

Returns:
list[kms.RetiredResource]: The list of retired resources.
"""

# Create the client.
client = kms.KeyManagementServiceClient()

# Build the parent location name.
parent = client.common_location_path(project_id, location_id)

# Call the API.
# The API paginates, but the Python client library handles that for us.
resources_list = list(client.list_retired_resources(request={"parent": parent}))

# Iterate over the resources and print them.
for resource in resources_list:
print(f"Retired resource: {resource.name}")

return resources_list


# [END kms_list_retired_resources]
2 changes: 1 addition & 1 deletion kms/snippets/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
google-cloud-kms==3.2.1
google-cloud-kms==3.11.0
cryptography==45.0.1
crcmod==1.7
jwcrypto==1.5.6
41 changes: 41 additions & 0 deletions kms/snippets/snippets_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
from create_key_version import create_key_version
from decrypt_asymmetric import decrypt_asymmetric
from decrypt_symmetric import decrypt_symmetric
from delete_key import delete_key
from destroy_key_version import destroy_key_version
from disable_key_version import disable_key_version
from enable_key_version import enable_key_version
Expand All @@ -62,10 +63,12 @@
from get_key_version_attestation import get_key_version_attestation
from get_public_key import get_public_key
from get_public_key_jwk import get_public_key_jwk
from get_retired_resource import get_retired_resource
from iam_add_member import iam_add_member
from iam_get_policy import iam_get_policy
from iam_remove_member import iam_remove_member
from import_manually_wrapped_key import import_manually_wrapped_key
from list_retired_resources import list_retired_resources
from quickstart import quickstart
from restore_key_version import restore_key_version
from sign_asymmetric import sign_asymmetric
Expand Down Expand Up @@ -886,3 +889,41 @@ def test_verify_mac(
def test_quickstart(project_id: str, location_id: str) -> None:
key_rings = quickstart(project_id, location_id)
assert key_rings


def test_delete_key_and_retired_resources(
client: kms.KeyManagementServiceClient,
project_id: str,
location_id: str,
key_ring_id: str,
) -> None:
# We can test key deletion and retired resources by first creating a key.
key_id = f"delete-key-{uuid.uuid4()}"
key_ring_name = client.key_ring_path(project_id, location_id, key_ring_id)
key = client.create_crypto_key(
request={
"parent": key_ring_name,
"crypto_key_id": key_id,
"crypto_key": {
"purpose": kms.CryptoKey.CryptoKeyPurpose.ENCRYPT_DECRYPT,
},
"skip_initial_version_creation": True,
}
)

# Delete the key.
delete_key(project_id, location_id, key_ring_id, key_id)

# List retired resources and filter to just our deleted key.
all_retired = list_retired_resources(project_id, location_id)
filtered_retired = [r for r in all_retired if r.original_resource == key.name]

# Make sure the len is 1
assert len(filtered_retired) == 1

# Get the retired resource
resource_id = filtered_retired[0].name.split("/")[-1]
retrieved = get_retired_resource(project_id, location_id, resource_id)

# See if the result is the same as retired resource list[0]
assert retrieved.name == filtered_retired[0].name