Destroying and restoring key versions

A key version has a state which determines if its key material exists.

A key version which is enabled or disabled can move to scheduled for destruction using DestroyCryptoKeyVersion, client library methods that map to DestroyCryptoKeyVersion, gcloud kms keys versions destroy, or the Google Cloud Platform Console. A key version which is scheduled for destruction can move to disabled using RestoreCryptoKeyVersion, client library methods that map to RestoreCryptoKeyVersion, gcloud kms keys versions restore, and the Google Cloud Platform Console.

To modify the state of a key version, a user needs the appropriate Cloud Identity and Access Management role or permission.

  • The pre-defined roles roles/cloudkms.admin or roles/owner can schedule a key version for destruction and can restore a key version that is scheduled for destruction.

  • A custom role that contains the cloudkms.cryptoKeyVersions.destroy permission can schedule a key version for destruction.

  • A custom role that contains the cloudkms.cryptoKeyVersions.restore permission can restore a key version that is scheduled for destruction.

Schedule a key version for destruction (Destroy a key version)

Only key versions which are enabled or disabled can be scheduled for destruction.

To prevent accidents, and damage from malicious individuals, when DestroyCryptoKeyVersion is used, the key material is NOT immediately destroyed. Rather, the key version moves to scheduled for destruction for 24 hours, after which it is automatically destroyed. There is no way to override this safety fallback.

Destruction is removal of the key material, but a record of the version still exists (e.g., the version number cannot be reused). This is NOT reversible - any data encrypted with this version will not be recoverable.

Console

  1. Go to the Cryptographic Keys page in the GCP Console.
    Go to the Cryptographic Keys page

  2. Click the name of the key ring that contains the key whose key version you will schedule for destruction.

  3. Click the key whose key version you want to schedule for destruction.

  4. Click the key version that you want to schedule for destruction.

  5. Click Destroy.

  6. When prompted to confirm the scheduling of the key version for destruction, enter the key name and then click Schedule Destruction.

Command-line

Destroy version 42 of key answer in key ring answers in the global location.

gcloud kms keys versions destroy 42 --location global \
  --keyring answers --key answer

C#

      public static object DestroyCryptoKeyVersion(string projectId, string locationId, string keyRingId, string cryptoKeyId, string versionId)
      {
          var cloudKms = CreateAuthorizedClient();
          // Generate the full path of the parent to use for destroying the crypto key Version.
          var parent = $"projects/{projectId}/locations/{locationId}/keyRings/{keyRingId}/cryptoKeys/{cryptoKeyId}/cryptoKeyVersions/{versionId}";
          DestroyCryptoKeyVersionRequest destroyRequest = new DestroyCryptoKeyVersionRequest();
          // Destroy crypto key version.
          var request = new ProjectsResource.LocationsResource.KeyRingsResource.CryptoKeysResource
              .CryptoKeyVersionsResource.DestroyRequest(cloudKms, destroyRequest, parent);
          var result = request.Execute();
          Console.Write($"Destroyed Crypto Key Version: {result.Name}");
          return 0;
      }

Go

func destroyCryptoKeyVersion(project, keyRing, key, version string) error {
	ctx := context.Background()
	authedClient, err := google.DefaultClient(ctx, cloudkms.CloudPlatformScope)
	if err != nil {
		return err
	}
	client, err := cloudkms.New(authedClient)
	if err != nil {
		return err
	}
	location := "global"
	parent := fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeyVersions/%s",
		project, location, keyRing, version)

	_, err = client.Projects.Locations.KeyRings.CryptoKeys.CryptoKeyVersions.Destroy(
		parent, &cloudkms.DestroyCryptoKeyVersionRequest{}).Do()
	if err != nil {
		return err
	}
	log.Print("Destroyed crypto key version.")

	return nil
}

Java

/**
 * Marks the given version of a crypto key to be destroyed at a scheduled future point.
 */
public static CryptoKeyVersion destroyCryptoKeyVersion(
    String projectId, String locationId, String keyRingId, String cryptoKeyId, String version)
    throws IOException {
  // Create the Cloud KMS client.
  CloudKMS kms = createAuthorizedClient();

  // The resource name of the cryptoKey version
  String cryptoKeyVersion = String.format(
      "projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s/cryptoKeyVersions/%s",
      projectId, locationId, keyRingId, cryptoKeyId, version);

  DestroyCryptoKeyVersionRequest destroyRequest = new DestroyCryptoKeyVersionRequest();

  CryptoKeyVersion destroyed = kms.projects().locations().keyRings().cryptoKeys()
      .cryptoKeyVersions()
      .destroy(cryptoKeyVersion, destroyRequest)
      .execute();

  System.out.println(destroyed);
  return destroyed;
}

Node.js

async function destroyCryptoKeyVersion(
  projectId = 'your-project-id', // Your GCP projectId
  keyRingId = 'my-key-ring', // Name of the crypto key version's key ring
  cryptoKeyId = 'my-key', // Name of the version's crypto key
  version = 1234 // The version's id
) {
  // Import the library and create a client
  const kms = require('@google-cloud/kms');
  const client = new kms.KeyManagementServiceClient();

  // The location of the crypto key versions's key ring, e.g. "global"
  const locationId = 'global';

  // Get the full path to the crypto key version
  const name = client.cryptoKeyVersionPath(
    projectId,
    locationId,
    keyRingId,
    cryptoKeyId,
    version
  );

  // destroys a crypto key version
  const [result] = await client.destroyCryptoKeyVersion({name});
  console.log(`Crypto key version ${result.name} destroyed.`);
}

PHP

/**
 * Destroy a CryptoKey version.
 *
 * @param string $projectId
 * @param string $keyRingId
 * @param string $cryptoKeyId
 * @param string $version
 * @param string $locationId [optional]
 * @return Google_Service_CloudKMS_CryptoKeyVersion
 */
function destroy_cryptokey_version($projectId, $keyRingId, $cryptoKeyId, $version, $locationId = 'global')
{
    // Instantiate the client, authenticate, and add scopes.
    $client = new Google_Client();
    $client->useApplicationDefaultCredentials();
    $client->addScope('https://www.googleapis.com/auth/cloud-platform');

    // Create the Cloud KMS client.
    $kms = new Google_Service_CloudKMS($client);

    // The resource name of the CryptoKey version.
    $parent = sprintf('projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s/cryptoKeyVersions/%s',
        $projectId,
        $locationId,
        $keyRingId,
        $cryptoKeyId,
        $version
    );

    // Destroy the CryptoKey version.
    $request = new Google_Service_CloudKMS_DestroyCryptoKeyVersionRequest();
    $kms->projects_locations_keyRings_cryptoKeys_cryptoKeyVersions->destroy(
        $parent,
        $request
    );

    printf('Destroyed version %s for cryptoKey %s in keyRing %s' . PHP_EOL, $version, $cryptoKeyId, $keyRingId);
}

Python

def destroy_crypto_key_version(
        project_id, location_id, key_ring_id, crypto_key_id, version_id):
    """Schedules a CryptoKeyVersion associated with a given CryptoKey and
    KeyRing for destruction 24 hours in the future."""

    # Creates an API client for the KMS API.
    kms_client = googleapiclient.discovery.build('cloudkms', 'v1')

    # Construct the resource name of the CryptoKeyVersion.
    name = (
        'projects/{}/locations/{}/keyRings/{}/cryptoKeys/{}/'
        'cryptoKeyVersions/{}'
        .format(
            project_id, location_id, key_ring_id, crypto_key_id, version_id))

    # Use the KMS API to schedule the CryptoKeyVersion for destruction.
    crypto_keys = kms_client.projects().locations().keyRings().cryptoKeys()
    request = crypto_keys.cryptoKeyVersions().destroy(name=name, body={})
    response = request.execute()

    print('CryptoKeyVersion {}\'s state has been set to {}.'.format(
        name, response['state']))

Ruby

# project_id    = "Your Google Cloud project ID"
# location_id   = "The location of the key ring"
# key_ring_id   = "The ID of the key ring"
# crypto_key_id = "The ID of the crypto key"
# version_id    = "Version of the crypto key"

require "google/apis/cloudkms_v1"

# Initialize the client and authenticate with the specified scope
Cloudkms = Google::Apis::CloudkmsV1
kms_client = Cloudkms::CloudKMSService.new
kms_client.authorization = Google::Auth.get_application_default(
  "https://www.googleapis.com/auth/cloud-platform"
)

# The resource name of the crypto key version
resource = "projects/#{project_id}/locations/#{location_id}/" +
           "keyRings/#{key_ring_id}/cryptoKeys/#{crypto_key_id}/" +
           "cryptoKeyVersions/#{version_id}"

# Destroy specific version of the crypto key
kms_client.destroy_crypto_key_version(
  resource,
  Cloudkms::DestroyCryptoKeyVersionRequest.new
)

puts "Destroyed version #{version_id} of #{crypto_key_id}"

For an example of how to receive an alert when a key version is scheduled for destruction, see Using Stackdriver Monitoring with Cloud KMS.

Restore a key version

A key version which is scheduled for destruction can be restored, so that it is not automatically destroyed. This moves the key version from scheduled for destruction to disabled.

Console

  1. Go to the Cryptographic Keys page in the GCP Console.
    Go to the Cryptographic Keys page

  2. Click the name of the key ring that contains the key whose key version you want to restore.

  3. Click the key whose key version you want to restore.

  4. Click the key version that you want to restore.

  5. Click Restore.

  6. When prompted to confirm restoration of the key version, click Restore.

Command-line

Restore version 42 of key answer in key ring answers in the global location.

gcloud kms keys versions restore 42 --location global \
  --keyring answers --key answer

C#

      public static object RestoreCryptoKeyVersion(string projectId, string locationId, string keyRingId, string cryptoKeyId, string versionId)
      {
          var cloudKms = CreateAuthorizedClient();
          // Generate the full path of the parent to use for restoring the crypto key Version.
          var parent = $"projects/{projectId}/locations/{locationId}/keyRings/{keyRingId}/cryptoKeys/{cryptoKeyId}/cryptoKeyVersions/{versionId}";
          RestoreCryptoKeyVersionRequest restoreRequest = new RestoreCryptoKeyVersionRequest();
          // Restore crypto key version.
          var request = new ProjectsResource.LocationsResource.KeyRingsResource.CryptoKeysResource
              .CryptoKeyVersionsResource.RestoreRequest(cloudKms, restoreRequest, parent);
          var result = request.Execute();
          Console.Write($"Restored Crypto Key Version: {result.Name}");
          return 0;
      }

Go

func restoreCryptoKeyVersion(project, keyRing, key, version string) error {
	ctx := context.Background()
	authedClient, err := google.DefaultClient(ctx, cloudkms.CloudPlatformScope)
	if err != nil {
		return err
	}
	client, err := cloudkms.New(authedClient)
	if err != nil {
		return err
	}
	location := "global"
	parent := fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeyVersions/%s",
		project, location, keyRing, version)

	_, err = client.Projects.Locations.KeyRings.CryptoKeys.CryptoKeyVersions.Restore(
		parent, &cloudkms.RestoreCryptoKeyVersionRequest{}).Do()
	if err != nil {
		return err
	}
	log.Print("Restored crypto key version.")

	return nil
}

Java

/**
 * Restores the given version of a crypto key that is currently scheduled for destruction.
 */
public static CryptoKeyVersion restoreCryptoKeyVersion(
    String projectId, String locationId, String keyRingId, String cryptoKeyId, String version)
    throws IOException {
  // Create the Cloud KMS client.
  CloudKMS kms = createAuthorizedClient();

  // The resource name of the cryptoKey version
  String cryptoKeyVersion = String.format(
      "projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s/cryptoKeyVersions/%s",
      projectId, locationId, keyRingId, cryptoKeyId, version);

  RestoreCryptoKeyVersionRequest restoreRequest = new RestoreCryptoKeyVersionRequest();

  CryptoKeyVersion restored = kms.projects().locations().keyRings().cryptoKeys()
      .cryptoKeyVersions()
      .restore(cryptoKeyVersion, restoreRequest)
      .execute();

  System.out.println(restored);
  return restored;
}

Node.js

async function restoreCryptoKeyVersion(
  projectId = 'your-project-id', // Your GCP projectId
  keyRingId = 'my-key-ring', // Name of the crypto key version's key ring
  cryptoKeyId = 'my-key', // Name of the version's crypto key
  version = 1234 // The version's id
) {
  // Import the library and create a client
  const kms = require('@google-cloud/kms');
  const client = new kms.KeyManagementServiceClient();

  // The location of the crypto key versions's key ring, e.g. "global"
  const locationId = 'global';

  // Get the full path to the crypto key version
  const name = client.cryptoKeyVersionPath(
    projectId,
    locationId,
    keyRingId,
    cryptoKeyId,
    version
  );

  // restores a crypto key version
  const [result] = await client.restoreCryptoKeyVersion({name});
  console.log(`Crypto key version ${result.name} restored.`);
}

PHP

/**
 * Restore a CryptoKey version.
 *
 * @param string $projectId
 * @param string $keyRingId
 * @param string $cryptoKeyId
 * @param string $version
 * @param string $locationId [optional]
 * @return Google_Service_CloudKMS_CryptoKeyVersion
 */
function restore_cryptokey_version($projectId, $keyRingId, $cryptoKeyId, $version, $locationId = 'global')
{
    // Instantiate the client, authenticate, and add scopes.
    $client = new Google_Client();
    $client->useApplicationDefaultCredentials();
    $client->addScope('https://www.googleapis.com/auth/cloud-platform');

    // Create the Cloud KMS client.
    $kms = new Google_Service_CloudKMS($client);

    // The resource name of the CryptoKey version.
    $parent = sprintf('projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s/cryptoKeyVersions/%s',
        $projectId,
        $locationId,
        $keyRingId,
        $cryptoKeyId,
        $version
    );

    // Restore the CryptoKey version.
    $request = new Google_Service_CloudKMS_RestoreCryptoKeyVersionRequest();
    $kms->projects_locations_keyRings_cryptoKeys_cryptoKeyVersions->restore(
        $parent,
        $request
    );

    printf('Restored version %s for cryptoKey %s in keyRing %s' . PHP_EOL, $version, $cryptoKeyId, $keyRingId);
}

Python

def restore_crypto_key_version(
        project_id, location_id, key_ring_id, crypto_key_id, version_id):
    """Restores a CryptoKeyVersion that is scheduled for destruction."""

    # Creates an API client for the KMS API.
    kms_client = googleapiclient.discovery.build('cloudkms', 'v1')

    # Construct the resource name of the CryptoKeyVersion.
    name = (
        'projects/{}/locations/{}/keyRings/{}/cryptoKeys/{}/'
        'cryptoKeyVersions/{}'
        .format(
            project_id, location_id, key_ring_id, crypto_key_id, version_id))

    # Use the KMS API to restore the CryptoKeyVersion.
    crypto_keys = kms_client.projects().locations().keyRings().cryptoKeys()
    request = crypto_keys.cryptoKeyVersions().restore(name=name, body={})
    response = request.execute()

    print('CryptoKeyVersion {}\'s state has been set to {}.'.format(
        name, response['state']))

Ruby

# project_id    = "Your Google Cloud project ID"
# location_id   = "The location of the key ring"
# key_ring_id   = "The ID of the key ring"
# crypto_key_id = "The ID of the crypto key"
# version_id    = "Version of the crypto key"

require "google/apis/cloudkms_v1"

# Initialize the client and authenticate with the specified scope
Cloudkms = Google::Apis::CloudkmsV1
kms_client = Cloudkms::CloudKMSService.new
kms_client.authorization = Google::Auth.get_application_default(
  "https://www.googleapis.com/auth/cloud-platform"
)

# The resource name of the crypto key version
resource = "projects/#{project_id}/locations/#{location_id}/" +
           "keyRings/#{key_ring_id}/cryptoKeys/#{crypto_key_id}/" +
           "cryptoKeyVersions/#{version_id}"

# Restore specific version of the crypto key
kms_client.restore_crypto_key_version(
  resource,
  Cloudkms::RestoreCryptoKeyVersionRequest.new
)

puts "Restored version #{version_id} of #{crypto_key_id}"

Was this page helpful? Let us know how we did:

Send feedback about...

Cloud KMS Documentation