Encrypt disks with customer-supplied encryption keys


This topic provides information about how to encrypt disks with customer-supplied encryption keys.

For information about disk encryption, see About disk encryption.

For information bout encrypting disks with customer-managed encryption keys (CMEK), see Protect resources by using Cloud KMS keys.

Using CSEKs means you provide your own encryption keys and Compute Engine uses your keys to protect the Google-generated keys used to encrypt and decrypt your data. Only users who can provide the correct key can use resources protected by a customer-supplied encryption key (CSEK).

Google does not store your keys on its servers and cannot access your protected data unless you provide the key. This also means that if you forget or lose your key, there is no way for Google to recover the key or to recover any data encrypted with the lost key.

When you delete a persistent disk, Google discards the cipher keys, rendering the data irretrievable. This process is irreversible.

Before you begin

  • Read about disks, images, and disk snapshots.
  • If you haven't already, set up authentication. Authentication is the process by which your identity is verified for access to Google Cloud services and APIs. To run code or samples from a local development environment, you can authenticate to Compute Engine as follows.

    Select the tab for how you plan to use the samples on this page:

    Console

    When you use the Google Cloud console to access Google Cloud services and APIs, you don't need to set up authentication.

    gcloud

    1. Install the Google Cloud CLI, then initialize it by running the following command:

      gcloud init
    2. Set a default region and zone.

    Python

    To use the Python samples on this page from a local development environment, install and initialize the gcloud CLI, and then set up Application Default Credentials with your user credentials.

    1. Install the Google Cloud CLI.
    2. To initialize the gcloud CLI, run the following command:

      gcloud init
    3. Create local authentication credentials for your Google Account:

      gcloud auth application-default login

    For more information, see Set up authentication for a local development environment.

    REST

    To use the REST API samples on this page in a local development environment, you use the credentials you provide to the gcloud CLI.

      Install the Google Cloud CLI, then initialize it by running the following command:

      gcloud init

Restrictions

For CSEK, the following restrictions apply:

General restrictions

Availability of customer-supplied encryption keys depends on the location of your billing account, not the location of the resource.

Customer-supplied encryption keys are not available for billing accounts that are in the following countries:

  • Brazil
  • India

Technical restrictions

  • You can only encrypt new persistent disks with your own key. You cannot encrypt existing persistent disks with your own key.

  • You cannot use your own keys with local SSDs because local SSDs don't persist beyond the life of a VM. Local SSDs are already protected with an ephemeral encryption key that Google does not retain.

  • Compute Engine does not store encryption keys with instance templates, so you need to store your own keys in KMS to encrypt disks in a managed instance group.

  • You can't suspend instances that have CSEK-protected disks attached.

Specifications

This section describes the encryption specification and the format of CSEK.

Encryption

Compute Engine uses your encryption key to protect Google's encryption keys with AES-256 encryption.

Required key format

It is up to you to generate and manage your key. You must provide a key that is a 256-bit string encoded in RFC 4648 standard base64 to Compute Engine.

The following is an example of a base64 encoded key, generated with the string "Hello from Google Cloud Platform"

SGVsbG8gZnJvbSBHb29nbGUgQ2xvdWQgUGxhdGZvcm0=

It can be generated using the following script:

read -sp "String:" ; \
    [[ ${#REPLY} == 32 ]] && \
        echo "$(echo -n "$REPLY" | base64)" || \
        (>&2 echo -e "\nERROR:Wrong Size"; false)

RSA key wrapping

In addition to encoding your key in base64, you can optionally wrap your key using an RSA public key certificate provided by Google, encode the key in base64, and then use that key in your requests.

RSA wrapping is a process in which you use a public key to encrypt your data. After that data has been encrypted with the public key, it can only be decrypted by the respective private key. In this case, the private key is known only to Google Cloud services. By wrapping your key using the RSA certificate, you ensure that only Google Cloud services can unwrap your key and use it to protect your data.

For more information, see RSA encryption.

To create an RSA-wrapped key for Compute Engine, do the following:

  1. Wrap your key using the public key provided in a certificate that Compute Engine manages. Make sure to wrap your key using OAEP padding, not PKCS #1 v1.5 padding.
  2. Encode your RSA-wrapped key using standard base64 encoding.

Download the public certificate maintained by Compute Engine from:

https://cloud-certs.storage.googleapis.com/google-cloud-csek-ingress.pem

There are many ways of generate and RSA-wrap your key; use a method that is familiar to you. The following are two examples of RSA-wrapping your key that you could use.

Example 1

The following instructions use the openssl command-line utility to RSA-wrap and encode a key.

  1. Optional: Generate a 256-bit (32-byte) random key. If you already have a key you want to use, you can skip this step. There are many ways you can generate a key. For example:

    $ head -c 32 /dev/urandom | LC_CTYPE=C tr '\n' = > mykey.txt
    
  2. Download the public key certificate:

    $  curl -s -O -L https://cloud-certs.storage.googleapis.com/google-cloud-csek-ingress.pem
  3. Extract the public key from the certificate:

    $ openssl x509 -pubkey -noout -in google-cloud-csek-ingress.pem > pubkey.pem
    
  4. RSA-wrap your key, making sure to replace mykey.txt with your own key file.

    $ openssl rsautl -oaep -encrypt -pubin -inkey pubkey.pem -in mykey.txt -out rsawrappedkey.txt
    
  5. Encode your RSA-wrapped key in base64.

    $ openssl enc -base64 -in rsawrappedkey.txt | tr -d '\n' | sed -e '$a\' > rsawrapencodedkey.txt
    

Example 2

The following is sample Python script that generates a 256-bit (32-byte) random string and creates a base64 encoded RSA-wrapped key using the cryptography library:

import argparse
import base64
import os
from typing import Optional

from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey
import requests


GOOGLE_PUBLIC_CERT_URL = (
    "https://cloud-certs.storage.googleapis.com/google-cloud-csek-ingress.pem"
)


def get_google_public_cert_key() -> RSAPublicKey:
    """
    Downloads the Google public certificate.

    Returns:
        RSAPublicKey object with the Google public certificate.
    """
    r = requests.get(GOOGLE_PUBLIC_CERT_URL)
    r.raise_for_status()

    # Load the certificate.
    certificate = x509.load_pem_x509_certificate(r.content, default_backend())

    # Get the certicate's public key.
    public_key = certificate.public_key()

    return public_key


def wrap_rsa_key(public_key: RSAPublicKey, private_key_bytes: bytes) -> bytes:
    """
    Use the Google public key to encrypt the customer private key.

    This means that only the Google private key is capable of decrypting
    the customer private key.

    Args:
        public_key: The public key to use for encrypting.
        private_key_bytes: The private key to be encrypted.

    Returns:
        private_key_bytes encrypted using the public_key. Encoded using
        base64.
    """
    wrapped_key = public_key.encrypt(
        private_key_bytes,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA1()),
            algorithm=hashes.SHA1(),
            label=None,
        ),
    )
    encoded_wrapped_key = base64.b64encode(wrapped_key)
    return encoded_wrapped_key


def main(key_file: Optional[str]) -> None:
    """
    This script will encrypt a private key with Google public key.

    Args:
        key_file: path to a file containing your private key. If not
            provided, a new key will be generated (256 bit).
    """
    # Generate a new 256-bit private key if no key is specified.
    if not key_file:
        customer_key_bytes = os.urandom(32)
    else:
        with open(key_file, "rb") as f:
            customer_key_bytes = f.read()

    google_public_key = get_google_public_cert_key()
    wrapped_rsa_key = wrap_rsa_key(google_public_key, customer_key_bytes)

    b64_key = base64.b64encode(customer_key_bytes).decode("utf-8")

    print(f"Base-64 encoded private key: {b64_key}")
    print(f"Wrapped RSA key: {wrapped_rsa_key.decode('utf-8')}")


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
    )
    parser.add_argument("--key_file", help="File containing your binary private key.")

    args = parser.parse_args()

    main(args.key_file)

Your key is now ready to use!

Use a RSA-wrapped key

Using the Google Cloud CLI, you can provide a regular key and a RSA-wrapped key in the same way.

In the API, use the sha256 property instead of rawKey if you want to use a RSA-wrapped key instead.

Encrypting resources with CSEK using the command-line tool

Setup

Encryption keys can be used through the Google Cloud CLI.

Download and install gcloud.

Key file

When you use the gcloud compute command-line tool to set your keys, you provide encoded keys using a key file that contains your encoded keys as a JSON list. A key file can contain multiple keys, letting you manage many keys in a single place. Alternatively, you can create single key files to handle each key separately. A key file is only usable with the gcloud CLI. When using REST, you must supply the key directly in your request.

Each entry in your key file must provide:

  • The fully qualified URI to the resource the key protects
  • The corresponding key
  • The type of key, either raw or rsa-encrypted

When you use the key file in your requests, the tool looks for matching resources and uses the respective keys. If no matching resources are found, the request fails.

An example key file looks like this:

[
  {
  "uri": "https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/disks/example-disk",
  "key": "acXTX3rxrKAFTF0tYVLvydU1riRZTvUNC4g5I11NY+c=",
  "key-type": "raw"
  },
  {
  "uri": "https://www.googleapis.com/compute/v1/projects/myproject/global/snapshots/my-private-snapshot",
  "key": "ieCx/NcW06PcT7Ep1X6LUTc/hLvUDYyzSZPPVCVPTVEohpeHASqC8uw5TzyO9U+Fka9JFHz0mBibXUInrC/jEk014kCK/NPjYgEMOyssZ4ZINPKxlUh2zn1bV+MCaTICrdmuSBTWlUUiFoDD6PYznLwh8ZNdaheCeZ8ewEXgFQ8V+sDroLaN3Xs3MDTXQEMMoNUXMCZEIpg9Vtp9x2oeQ5lAbtt7bYAAHf5l+gJWw3sUfs0/Glw5fpdjT8Uggrr+RMZezGrltJEF293rvTIjWOEB3z5OHyHwQkvdrPDFcTqsLfh+8Hr8g+mf+7zVPEC8nEbqpdl3GPv3A7AwpFp7MA==",
  "key-type": "rsa-encrypted"
  }
]

Best practices for managing your key file

If you use a key file, restrict access to your file to only those who need it. Make sure to set appropriate permissions on these files and consider encrypting these files using additional tools:

Encrypt a new persistent disk with CSEK

You can encrypt a new persistent disk by supplying a key during VM or disk creation.

Console

  1. Go to the Disks page.

    Go to Disks

  2. Click Create disk and enter the properties for the new disk.

  3. Under Encryption, select Customer-supplied key.

  4. Provide the encryption key for the disk in the text box and select Wrapped key if the key has been wrapped with the public RSA key.

gcloud

In the gcloud compute tool, encrypt a disk using the --csek-key-file flag during VM creation. If you are using an RSA-wrapped key, use the gcloud beta component:

gcloud (beta) compute instances create example-instance --csek-key-file example-file.json

To encrypt a standalone persistent disk:

gcloud (beta) compute disks create example-disk --csek-key-file example-file.json

REST

You can encrypt a disk by using the diskEncryptionKey property and making a request to the v1 API for a raw (non-RSA wrapped) key, or to the Beta API for a RSA-wrapped key. Provide one of the following properties in your request:

  • rawKey: if your key is base64 encoded
  • rsaEncryptedKey: if your key is RSA-wrapped and base64 encoded

For example, to encrypt a new disk during VM creation with an RSA-wrapped key:

POST https://compute.googleapis.com/compute/beta/projects/myproject/zones/us-central1-a/instances

{
"machineType": "zones/us-central1-a/machineTypes/e2-standard-2",
"disks": [
 {
  "type": "PERSISTENT",
  "diskEncryptionKey": {
    "rsaEncryptedKey": "ieCx/NcW06PcT7Ep1X6LUTc/hLvUDYyzSZPPVCVPTVEohpeHASqC8uw5TzyO9U+Fka9JFHz0mBibXUInrC/jEk014kCK/NPjYgEMOyssZ4ZINPKxlUh2zn1bV+MCaTICrdmuSBTWlUUiFoDD6PYznLwh8ZNdaheCeZ8ewEXgFQ8V+sDroLaN3Xs3MDTXQEMMoNUXMCZEIpg9Vtp9x2oeQ5lAbtt7bYAAHf5l+gJWw3sUfs0/Glw5fpdjT8Uggrr+RMZezGrltJEF293rvTIjWOEB3z5OHyHwQkvdrPDFcTqsLfh+8Hr8g+mf+7zVPEC8nEbqpdl3GPv3A7AwpFp7MA=="
  },
  "initializeParams": {
   "sourceImage": "projects/debian-cloud/global/images/debian-9-stretch-v20170619"
  },
  "boot": true
 }
],
...
}

Similarly, you can also use REST to create a new standalone persistent disk and encrypt it with your own key:

POST https://compute.googleapis.com/compute/beta/projects/myproject/zones/
us-central1-a/disks?sourceImage=https%3A%2F%2Fwww.googleapis.com%2Fcompute%2F
alpha%2Fprojects%2Fdebian-cloud%2Fglobal%2Fimages%2Fdebian-9-stretch-v20170619

{
 "name": "new-encrypted-disk-key",
 "diskEncryptionKey": {
   "rsaEncryptedKey": "ieCx/NcW06PcT7Ep1X6LUTc/hLvUDYyzSZPPVCVPTVEohpeHASqC8uw5TzyO9U+Fka9JFHz0mBibXUInrC/jEk014kCK/NPjYgEMOyssZ4ZINPKxlUh2zn1bV+MCaTICrdmuSBTWlUUiFoDD6PYznLwh8ZNdaheCeZ8ewEXgFQ8V+sDroLaN3Xs3MDTXQEMMoNUXMCZEIpg9Vtp9x2oeQ5lAbtt7bYAAHf5l+gJWw3sUfs0/Glw5fpdjT8Uggrr+RMZezGrltJEF293rvTIjWOEB3z5OHyHwQkvdrPDFcTqsLfh+8Hr8g+mf+7zVPEC8nEbqpdl3GPv3A7AwpFp7MA=="
  },
 "type": "zones/us-central1-a/diskTypes/pd-standard"
}

Create a snapshot from a disk encrypted with CSEK

If you create a snapshot from an encrypted disk, the snapshot must also be encrypted. You must specify a key to encrypt the snapshot. You cannot convert encrypted disks or encrypted snapshots to use Compute Engine default encryption unless you create a new disk image and a new persistent disk.

Snapshots of disks encrypted with CSEK are always full snapshots. This differs from snapshots of disks encrypted with customer-managed encryption keys (CMEK), which are incremental. Snapshots are priced based on the total size of the snapshot, so a full snapshot might cost more than an incremental snapshot.

To create a persistent disk snapshot from an encrypted disk, your snapshot creation request must provide the encryption key that you used to encrypt the persistent disk.

Review the Best practices for persistent disk snapshots before creating your snapshot.

Console

  1. Go to the Snapshots page.

    Go to Snapshots

  2. Click Create snapshot.

  3. Under Source disk, choose the encrypted disk you want to create a snapshot of.

  4. Provide the encryption key for the disk in the text box and select Wrapped key if the key has been wrapped with the public RSA key.

  5. Encrypt the new snapshot by supplying an additional encryption key under the Encryption section.

REST

To make the request, provide the sourceDiskEncryptionKey property to access the source persistent disk. You must encrypt the new snapshot using the snapshotEncryptionKey property.

Make a request to the v1 API for a raw (non-RSA wrapped) key, or to the Beta API for a RSA-wrapped key.

POST https://compute.googleapis.com/compute/beta/projects/myproject/zones/us-central1-a/disks/example-disk/createSnapshot

{
 "snapshotEncryptionKey":  {
   "rsaEncryptedKey": "ieCx/NcW06PcT7Ep1X6LUTc/hLvUDYyzSZPPVCVPTVEohpeHASqC8uw5TzyO9U+Fka9JFHz0mBibXUInrC/jEk014kCK/NPjYgEMOyssZ4ZINPKxlUh2zn1bV+MCaTICrdmuSBTWlUUiFoDD6PYznLwh8ZNdaheCeZ8ewEXgFQ8V+sDroLaN3Xs3MDTXQEMMoNUXMCZEIpg9Vtp9x2oeQ5lAbtt7bYAAHf5l+gJWw3sUfs0/Glw5fpdjT8Uggrr+RMZezGrltJEF293rvTIjWOEB3z5OHyHwQkvdrPDFcTqsLfh+8Hr8g+mf+7zVPEC8nEbqpdl3GPv3A7AwpFp7MA=="
 },
  "sourceDiskEncryptionKey": {
   "rsaEncryptedKey": "ieCx/NcW06PcT7Ep1X6LUTc/hLvUDYyzSZPPVCVPTVEohpeHASqC8uw5TzyO9U+Fka9JFHz0mBibXUInrC/jEk014kCK/NPjYgEMOyssZ4ZINPKxlUh2zn1bV+MCaTICrdmuSBTWlUUiFoDD6PYznLwh8ZNdaheCeZ8ewEXgFQ8V+sDroLaN3Xs3MDTXQEMMoNUXMCZEIpg9Vtp9x2oeQ5lAbtt7bYAAHf5l+gJWw3sUfs0/Glw5fpdjT8Uggrr+RMZezGrltJEF293rvTIjWOEB3z5OHyHwQkvdrPDFcTqsLfh+8Hr8g+mf+7zVPEC8nEbqpdl3GPv3A7AwpFp7MA=="
  },
 "name": "snapshot-encrypted-disk"
}

The sourceDiskEncryptionKey property must match the key used to encrypt the persistent disk. Otherwise, the request fails.

The snapshotEncryptionKey lets you to supply a key to encrypt the snapshot so that if the snapshot is used to create new persistent disks, a matching key must be provided. This key must follow the preceding key format. You can also choose to leave this property undefined and the snapshot can be used to create new persistent disks without requiring a key.

Create a new image from a disk or custom image encrypted with CSEK

You can create custom images from encrypted persistent disks or copy encrypted images. You cannot use the console to copy images. Use the Google Cloud CLI or REST to copy images.

Console

  1. Go to the Images page.

    Go to Images

  2. Click Create image.

  3. Under Source disk, choose the encrypted disk you want to create an image of.

  4. Under Encryption, select an encryption key management solution.

  5. If the key has been wrapped with the public RSA key, select Wrapped key.

gcloud

Follow the instructions to create an image, and add the --csek-key-file flag with a path to the encryption key file for the encrypted source object. Use the gcloud beta component if you are using an RSA-wrapped key:

gcloud (beta) compute images create .... --csek-key-file example-file.json

If you want to encrypt the new image with your key, add the key to the key file:

[
  {
  "uri": "https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/disks/source-disk",
  "key": "acX3RqzxrKAFTF0tYVLvydU1riRZTvUNC4g5I11NY-c=",
  "key-type": "raw"
  },
  {
  "uri": "https://www.googleapis.com/compute/v1/projects/myproject/global/snapshots/the-new-image",
  "key": "TF0t-cSfl7CT7xRF1LTbAgi7U6XXUNC4zU_dNgx0nQc=",
  "key-type": "raw"
  }
]

REST

Your API creation request must contain the encryption key property for your source object. For example, include one of the following properties depending on the source object type:

  • Persistent disk: sourceDiskEncryptionKey
  • Image: sourceImageEncryptionKey

Also include the rawKey or rsaEncryptedKey properties depending on key type. Make a request to the v1 API for a raw (non-RSA wrapped) key, or to the Beta API for a RSA-wrapped key. The following example converts an encrypted and RSA-wrapped persistent disk to an image that uses the same encryption key.

POST https://compute.googleapis.com/compute/beta/projects/myproject/global/images

{
 "name": "image-encrypted-disk",
 "sourceDiskEncryptionKey": {
    "rsaEncryptedKey": "ieCx/NcW06PcT7Ep1X6LUTc/hLvUDYyzSZPPVCVPTVEohpeHASqC8uw5TzyO9U+Fka9JFHz0mBibXUInrC/jEk014kCK/NPjYgEMOyssZ4ZINPKxlUh2zn1bV+MCaTICrdmuSBTWlUUiFoDD6PYznLwh8ZNdaheCeZ8ewEXgFQ8V+sDroLaN3Xs3MDTXQEMMoNUXMCZEIpg9Vtp9x2oeQ5lAbtt7bYAAHf5l+gJWw3sUfs0/Glw5fpdjT8Uggrr+RMZezGrltJEF293rvTIjWOEB3z5OHyHwQkvdrPDFcTqsLfh+8Hr8g+mf+7zVPEC8nEbqpdl3GPv3A7AwpFp7MA=="
  }
 "imageEncryptionKey": {
    "rsaEncryptedKey":  "ieCx/NcW06PcT7Ep1X6LUTc/hLvUDYyzSZPPVCVPTVEohpeHASqC8uw5TzyO9U+Fka9JFHz0mBibXUInrC/jEk014kCK/NPjYgEMOyssZ4ZINPKxlUh2zn1bV+MCaTICrdmuSBTWlUUiFoDD6PYznLwh8ZNdaheCeZ8ewEXgFQ8V+sDroLaN3Xs3MDTXQEMMoNUXMCZEIpg9Vtp9x2oeQ5lAbtt7bYAAHf5l+gJWw3sUfs0/Glw5fpdjT8Uggrr+RMZezGrltJEF293rvTIjWOEB3z5OHyHwQkvdrPDFcTqsLfh+8Hr8g+mf+7zVPEC8nEbqpdl3GPv3A7AwpFp7MA=="
    },
 "sourceDisk": "projects/myproject/zones/us-central1-a/disks/source-disks"
}

The optional imageEncryptionKey property lets you supply a key to encrypt the image so when the image is used to create new persistent disks, a matching key must be provided. This key must follow the same key format described above. You can also choose to leave this property undefined and the image can be used to create new persistent disks without requiring a key.

Encrypt an imported image with CSEK

You can encrypt a new image when you manually import a custom image to Compute Engine. Before you can import an image, you must create and compress a disk image file and upload that compressed file to Cloud Storage.

Import the custom Compute Engine image that you want to encrypt. Specify the URI to the compressed file and also specify a path to your encryption key file.

Console

  1. Go to the Images page.

    Go to Images

  2. Click Create image.

  3. Under Source, choose Cloud Storage file.

  4. Under Cloud Storage file, enter the Cloud Storage URI.

  5. Under Encryption, choose Customer-supplied key and provide the encryption key to encrypt the image in the text box.

gcloud

Use the compute images create command to create a new image, and specify the --csek-key-file flag with an encryption key file. If you are using an RSA-wrapped key, use the gcloud beta component:

gcloud (beta) compute images create [IMAGE_NAME] \
    --source-uri gs://[BUCKET_NAME]/[COMPRESSED_FILE] \
    --csek-key-file [KEY_FILE]

Replace the following:

  • [IMAGE_NAME]: the name for the new custom image.
  • [BUCKET_NAME]: the name of the Cloud Storage bucket that holds your compressed image file.
  • [COMPRESSED_FILE]: the name of the compressed image file.
  • [KEY_FILE]: the path to an encryption key file on your local workstation.

REST

To encrypt a new image created from a RAW file, add the new imageEncryptionKey property to the image creation request, followed by either rawKey or rsaEncryptedKey. Make a request to the v1 API for a raw (non-RSA wrapped) key, or to the Beta API for a RSA-wrapped key.

POST https://compute.googleapis.com/compute/beta/projects/myproject/global/images

{
"rawDisk": {
 "source": "http://storage.googleapis.com/example-image/example-image.tar.gz"
},
"name": "new-encrypted-image",
"sourceType": "RAW",
"imageEncryptionKey": {
  "rsaEncryptedKey": "ieCx/NcW06PcT7Ep1X6LUTc/hLvUDYyzSZPPVCVPTVEohpeHASqC8uw5TzyO9U+Fka9JFHz0mBibXUInrC/jEk014kCK/NPjYgEMOyssZ4ZINPKxlUh2zn1bV+MCaTICrdmuSBTWlUUiFoDD6PYznLwh8ZNdaheCeZ8ewEXgFQ8V+sDroLaN3Xs3MDTXQEMMoNUXMCZEIpg9Vtp9x2oeQ5lAbtt7bYAAHf5l+gJWw3sUfs0/Glw5fpdjT8Uggrr+RMZezGrltJEF293rvTIjWOEB3z5OHyHwQkvdrPDFcTqsLfh+8Hr8g+mf+7zVPEC8nEbqpdl3GPv3A7AwpFp7MA=="
  }
}

Create a persistent disk from a resource encrypted with CSEK

Create a disk from a snapshot encrypted with CSEK

Console

  1. Go to the Disks page.

    Go to Disks

  2. Click Create disk.

  3. Under Source type, select Snapshot.

  4. Under Encryption, select an encryption key management solution.

  5. If the key has been wrapped with the public RSA key, select Wrapped key.

gcloud

In the gcloud compute tool, provide the encryption key for the snapshot using the --csek-key-file flag when you create the disk. If you are using an RSA-wrapped key, use the gcloud beta component:

gcloud (beta) compute disks create ... --source-snapshot example-snapshot --csek-key-file example-file.json

REST

To use an encrypted snapshot, supply the sourceSnapshotEncryptionKey in your request, followed by rawKey or rsaEncryptedKey. Make a request to the v1 API for a raw (non-RSA wrapped) key, or to the Beta API for a RSA-wrapped key. For example, to a new standalone persistent disk using an encrypted snapshot:

POST https://compute.googleapis.com/compute/beta/projects/myproject/zones/us-central1-a/disks

{
"name": "disk-from-encrypted-snapshot",
"sourceSnapshot": "global/snapshots/encrypted-snapshot",
"sourceSnapshotEncryptionKey": {
  "rsaEncryptedKey": "ieCx/NcW06PcT7Ep1X6LUTc/hLvUDYyzSZPPVCVPTVEohpeHASqC8uw5TzyO9U+Fka9JFHz0mBibXUInrC/jEk014kCK/NPjYgEMOyssZ4ZINPKxlUh2zn1bV+MCaTICrdmuSBTWlUUiFoDD6PYznLwh8ZNdaheCeZ8ewEXgFQ8V+sDroLaN3Xs3MDTXQEMMoNUXMCZEIpg9Vtp9x2oeQ5lAbtt7bYAAHf5l+gJWw3sUfs0/Glw5fpdjT8Uggrr+RMZezGrltJEF293rvTIjWOEB3z5OHyHwQkvdrPDFcTqsLfh+8Hr8g+mf+7zVPEC8nEbqpdl3GPv3A7AwpFp7MA=="
  }
}

Create a disk from an image encrypted with CSEK

Console

  1. Go to the Disks page.

    Go to Disks

  2. Click Create disk.

  3. Under Source type, select Image.

  4. Under Encryption, select an encryption key management solution.

  5. If the key has been wrapped with the public RSA key, select Wrapped key.

gcloud

In the gcloud compute tool, provide the encryption key for the image using the --csek-key-file flag when you create the disk. If you are using an RSA-wrapped key, use the gcloud beta component:

gcloud (beta) compute disks create ... --image example-image --csek-key-file example-file.json

REST

To use an encrypted image, provide the sourceImageEncryptionKey, followed by either rawKey or rsaEncryptedKey. Make a request to the v1 API for a raw (non-RSA wrapped) key, or to the Beta API for a RSA-wrapped key.

POST https://compute.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/disks

{
"name": "disk-from-encrypted-image",
"sourceImageEncryptionKey": {
  "rsaEncryptedKey": "ieCx/NcW06PcT7Ep1X6LUTc/hLvUDYyzSZPPVCVPTVEohpeHASqC8uw5TzyO9U+Fka9JFHz0mBibXUInrC/jEk014kCK/NPjYgEMOyssZ4ZINPKxlUh2zn1bV+MCaTICrdmuSBTWlUUiFoDD6PYznLwh8ZNdaheCeZ8ewEXgFQ8V+sDroLaN3Xs3MDTXQEMMoNUXMCZEIpg9Vtp9x2oeQ5lAbtt7bYAAHf5l+gJWw3sUfs0/Glw5fpdjT8Uggrr+RMZezGrltJEF293rvTIjWOEB3z5OHyHwQkvdrPDFcTqsLfh+8Hr8g+mf+7zVPEC8nEbqpdl3GPv3A7AwpFp7MA=="
  },
"sourceImage": "global/images/encrypted-image"
}

Attaching a disk encrypted with CSEK to a new VM

Console

  1. Go to the Create an instance page.

    Go to Create an instance

  2. In the Boot disk section, click Change, and do the following:

    1. On the Boot disk page, click the Existing disks tab.
    2. From the Disk list, choose an existing encrypted disk to attach to the VM.
    3. Enter the encryption key in the text box and select Wrapped key if the key has been wrapped with the public RSA key.

    4. Click Select.

  3. Continue with the VM creation process.

gcloud

To create a VM and attach an encrypted disk, create a key file and provide the key using the --csek-key-file flag when you create the VM. If you are using an RSA-wrapped key, use the gcloud beta component:

gcloud (beta) compute instances create example-instance \
    --disk name=example-disk,boot=yes \
    --csek-key-file example-file.json

REST

Create a VM using the Compute Engine API and provide either the rawKey or rsaEncryptedKey with the disk specification. Make a request to the v1 API for a raw (non-RSA wrapped) key, or to the Beta API for a RSA-wrapped key.

Here is a snippet of an example disk specification:

"disks": [
{
  "deviceName": "encrypted-disk",
  "source": "projects/myproject/zones/us-central1-f/disks/encrypted-disk",
  "diskEncryptionKey": {
    "rawKey": "SGVsbG8gZnJvbSBHb29nbGUgQ2xvdWQgUGxhdGZvcm0="
  }
 }
]

Starting or restarting VMs that have disks encrypted with CSEK

For details on stopping or starting a VM that has encrypted disks, read Restarting a VM with an encrypted disk.

Using the command line to create mixed resources

If you want to create a mix of customer-encrypted and standard-encrypted resources in a single request with the Google Cloud CLI, you can use the --csek-key-file flag with a key file and the --no-require-csek-key-create flag in your request. By providing both flags, gcloud CLI creates any customer-encrypted resources that are explicitly define in your key file and also creates any standard resources you specify.

For example, assume a key file contains the following:

[
  {
  "uri": "https://www.googleapis.com/compute/beta/projects/myproject/zones/us-central1-a/disks/example-disk",
  "key": "ieCx/NcW06PcT7Ep1X6LUTc/hLvUDYyzSZPPVCVPTVEohpeHASqC8uw5TzyO9U+Fka9JFHz0mBibXUInrC/jEk014kCK/NPjYgEMOyssZ4ZINPKxlUh2zn1bV+MCaTICrdmuSBTWlUUiFoDD6PYznLwh8ZNdaheCeZ8ewEXgFQ8V+sDroLaN3Xs3MDTXQEMMoNUXMCZEIpg9Vtp9x2oeQ5lAbtt7bYAAHf5l+gJWw3sUfs0/Glw5fpdjT8Uggrr+RMZezGrltJEF293rvTIjWOEB3z5OHyHwQkvdrPDFcTqsLfh+8Hr8g+mf+7zVPEC8nEbqpdl3GPv3A7AwpFp7MA==",
  "key-type": "rsa-encrypted"
  }
]

If you wanted to create a VM with a customer-encrypted disk using the key file and simultaneously create a VM with a standard-encrypted disk in the same request, you can do so as follows:

gcloud beta compute instances create example-disk example-disk-2 \
    --csek-key-file mykeyfile.json --no-require-csek-key-create

Normally, it would not be possible to create example-disk-2 if you specified the --csek-key-file flag because the disk is not explicitly defined in the key file. By adding the --no-require-csek-key-create, both disks are created, one encrypted using the key file, and the other encrypted using Google encryption.

Remove your CSEK from a persistent disk

You can decrypt the contents of a customer-encrypted disk and create a new disk that uses Compute Engine default encryption instead.

  1. Create an image of the encrypted disk and specify automatic encryption for the new image.
  2. Use the new image to create a new persistent disk.

After you create the new persistent disk, it uses Compute Engine default encryption to protect the disk contents. Any snapshots that you create from that disk must also use default encryption.