Use customer-managed encryption keys (CMEK)

This page describes how to perform tasks related to customer-managed encryption keys (CMEK) for Firestore. For more information about CMEK in general, including when and why to enable it, see the Cloud KMS documentation.

Prepare your CMEK keys

Before you can create a CMEK-protected Firestore database, you must complete the following steps:

  1. Request access to the Firestore CMEK feature.
  2. Create (or retrieve) a Firestore service agent.
  3. Create a CMEK key.
  4. Configure IAM settings for that key.

Complete these steps for each project that will contain CMEK-protected Firestore databases. If you later create a new CMEK key, you must configure IAM settings for that key.

Request access

Before you create a Firestore service agent, request access to the CMEK feature by filling in this form.

Create a Firestore service agent

Before you create a CMEK key, you must have a Firestore service agent, which is a type of Google-managed service account that Firestore uses to access the key.

Run the services identity create command to create the service agent that Firestore uses to access the CMEK key on your behalf. This command creates the service account if it does not already exist, then displays it.

gcloud beta services identity create \
    --service=firestore.googleapis.com \
    --project FIRESTORE_PROJECT

Replace FIRESTORE_PROJECT with the project you plan to use for your Firestore databases.

The command displays the service agent ID, which is formatted like an email address. Record the output email string, because you'll use it in a later step.

Service identity created:
service-xxx@gcp-sa-firestore.iam.gserviceaccount.com

Create a key

You can use a key created directly in Cloud KMS or an externally managed key that you make available with Cloud External Key Manager.

The Cloud KMS key location must be the same as the location of the Firestore database that it will be used with.

  • For regional database locations, use the same location name for key ring, key, and database because the location names have a one-to-one mapping.

    For example, if you want to create a CMEK-protected database in us-west1, create a key ring and key in us-west1.

  • For multi-region database locations, use the location name of the KMS multi-region location:

    • Use the Cloud KMS us multi-region location for the Firestore nam5 multi-region location.
    • Use the Cloud KMS europe multi-region location for the Firestore eur3 multi-region location.

In the Google Cloud project where you want to manage your keys, complete the following:

  1. Enable the Cloud KMS API.

  2. Create a key ring and a key using one of the following options:

Configure IAM settings for the key

Console

To grant an Cloud KMS role to your service agent, do the following. You are also able to grant permission at the key or key-ring level if you want lower granularity.

  1. In the Google Cloud console, go to the IAM page.

    Go to the IAM page

  2. Click Add.

  3. Enter the email-formatted ID for your Firestore service agent.

  4. Select the Cloud KMS CryptoKey Encrypter/Decrypter role.

  5. Click Save.

gcloud

Grant the cloudkms.cryptoKeyEncrypterDecrypter role to your service agent:

gcloud kms keys add-iam-policy-binding KMS_KEY \
--keyring KMS_KEYRING\
--location KMS_LOCATION \
--member serviceAccount:SERVICE_AGENT_EMAIL \
--role roles/cloudkms.cryptoKeyEncrypterDecrypter \
--project KMS_PROJECT

Replace the following:

  • KMS_KEY with the name that you assigned to the key
  • KMS_KEYRING with the KMS key ring that contains the key
  • KMS_LOCATION with the region that contains the key ring
  • SERVICE_AGENT_EMAIL with the email-formatted identifier for the service agent that you are granting access to
  • KMS_PROJECT with the project that contains the key

The terminal should display a response similar to the following:

Updated IAM policy for key KMS_KEY.
bindings:
- members:
- serviceAccount:
service-{project-number}@gcp-sa-firestore.iam.gserviceaccount.com
role: roles/cloudkms.cryptoKeyEncrypterDecrypter

Create a CMEK-enabled database

After your CMEK keys are created and configured, you can create a CMEK-protected database. Existing Firestore databases that are protected by Google default encryption can't be converted to use CMEK.

You can choose an encryption type and key only when you create a CMEK-enabled database.

Console

  1. In the Google Cloud console, go to the Databases page.

    Go to the Databases page

  2. Click Create Database.

  3. Select your database mode. Click Continue.

  4. On the Configure your database page, enter a database ID.

  5. Select a location.

  6. Click Show Encryption Options, and then select Cloud KMS key.

  7. Select or enter the resource name for the CMEK key that you want to use for the database.

  8. The list of keys is limited to the current Google Cloud project and the database location that you selected. To use a key from a different Google Cloud project, click Switch Project or Enter Key Manually.

  9. If you are prompted to grant key permission to the Firestore service account, click Grant. To create a CMEK database, your Firestore service account must be granted the cloudkms.cryptoKeyEncrypterDecrypter role.

  10. Select security rules for mobile and web clients.

  11. Click Create Database.

Once the database is created, you can verify that the database is CMEK-enabled by viewing Database details:

  • If your database is protected by CMEK, the Encryption type field shows as Customer-managed and the Encryption key field lists the corresponding Cloud KMS and the key version that is used to protect this database.
  • If your database is not protected by CMEK, the Encryption type field shows as Google-managed.

gcloud

Before you create a CMEK-enabled database with Google Cloud CLI, install the latest version and authorize the gcloud CLI. For more information, see Install the gcloud CLI.

gcloud firestore databases create --location=FIRESTORE_DATABASE_LOCATION \
      --database=DATABASE_ID \
      --kms-key-name=KMS_KEY_NAME \
      --project=FIRESTORE_PROJECT

Replace the following:

  • FIRESTORE_DATABASE_LOCATION with the Firestore location for the database
  • DATABASE_ID with an ID for the database
  • KMS_KEY_NAME with the name you assigned to the key. Use the full resource name for the key in the following format:

    projects/KMS_PROJECT/locations/KMS_LOCATION/keyRings/KMS_KEYRING_ID/cryptoKeys/KMS_KEY_ID

  • FIRESTORE_PROJECT with the project to use for your Firestore database

REST API

HTTP request:

POST https://firestore.googleapis.com/v1/projects/{FIRESTORE_PROJECT}/databases

In the request body configure CMEK in the cmek_config.kms_key_name field.

Set to the full resource ID of a Cloud KMS key. Only a key in the same location as this database is allowed.

This value should be the Cloud KMS key resource ID in the format of projects/{KMS_PROJECT}/locations/{KMS_LOCATION}/keyRings/{KMS_KEYRING_ID}/cryptoKeys/{KMS_KEY_ID}

For more information about other fields, see the database create page.

Example request:

curl -X POST 'https://firestore.googleapis.com/v1/projects/FIRESTORE_PROJECT/databases?databaseId={DATABASE_ID}' \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-type: application/json" \
-d '{
  "type":"FIRESTORE_NATIVE",
  "locationId":"{FIRESTORE_DATABASE_LOCATION}",
  "cmekConfig": {
    "kmsKeyName":"projects/KMS_PROJECT/locations/KMS_LOCATION/keyRings/KMS_KEYRING_ID/cryptoKeys/KMS_KEY_ID"
  }
}'

Firebase CLI

To create a CMEK-enabled database, use the KMS Key Name field. If you don't specify the --kms-key-name parameter, Firestore creates a non-CMEK database by default.

firebase firestore:databases:create DATABASE_ID
--location LOCATION
--kms-key-name projects/KMS_PROJECT/locations/KMS_LOCATION/keyRings/KMS_KEYRING_ID/cryptoKeys/KMS_KEY_ID
--project FIRESTORE_PROJECT

Replace the following:

  • DATABASE_ID with the ID of your database
  • LOCATION with the location of your database
  • KMS_PROJECT with the project that contains your CMEK key
  • KMS_LOCATION with the location that contains your CMEK key and key ring
  • KMS_KEYRING_ID with the ID of your CMEK key ring
  • FIRESTORE_PROJECT with the project to use for your Firestore database

Confirm that your Firestore database is protected with Firebase CLI:

firebase firestore:databases:get DATABASE_ID --project FIRESTORE_PROJECT

The following CMEK information appears in the response message:

  • The KMS Key Name field provides the full key resource name that is used to encrypt your Firestore CMEK database.
  • The Active Key Versions field provides a list of all key versions currently used by this CMEK database. During key rotation, you can have multiple active key versions.

Terraform

To create a CMEK-enabled database, use the google_firestore_database resource. For more information and examples, see google_firestore_database.

resource "google_firestore_database" "database" {
  project     = "FIRESTORE_PROJECT"
  name        = "DATABASE_ID"
  location_id = "FIRESTORE_DATABASE_LOCATION"
  type        = "DATABASE_TYPE"

  cmek_config {
    kms_key_name = "KMS_KEY_NAME"
  }
}

Replace the following:

  • FIRESTORE_PROJECT with the project to use for your Firestore database
  • DATABASE_ID with an ID for the database
  • FIRESTORE_DATABASE_LOCATION with the Firestore location for the database
  • DATABASE_TYPE with either FIRESTORE_NATIVE for Native mode or DATASTORE_MODE for Datastore mode.
  • KMS_KEY_NAME with the name you assigned to the key. Use the full resource name for the key in the format of:

    projects/KMS_PROJECT/locations/KMS_LOCATION/keyRings/KMS_KEYRING_ID/cryptoKeys/KMS_KEY_ID

Access a CMEK-protected database

All the read, write, and query operations sent to a CMEK-protected database should function the same as with a Google default encrypted database. For example, you don't need to provide a key for each request.

Restore a CMEK-protected database

Before you restore CMEK-protected database from a backup:

  • Decide if you want to restore the database to CMEK encryption, to Google's default encryption (non-CMEK), or to the same encryption as the backup.
  • Prepare the key (primary-version) and the key version that you used to encrypt the backup. Enable both the key and the key version.

gcloud

Restore a CMEK-protected database to CMEK encryption

To restore to CMEK encryption, run the gcloud firestore databases restore command with the optional encryption-type and kms-key-name flags to configure the encryption type for the restored database. If you don't specify the encryption type, the restored database will use the same encryption configuration as the backup.

  gcloud firestore databases restore
  --encryption-type=customer-managed-encryption
  --kms-key-name=KMS_KEY_NAME

Replace KMS_KEY_NAME with the name that you assigned to the key. Use the full resource name for the key in the following format:

projects/KMS_PROJECT/locations/KMS_LOCATION/keyRings/KMS_KEYRING_ID/cryptoKeys/KMS_KEY_ID

Restore a CMEK-protected database to default encryption

To restore to Google's default encryption (non-CMEK), set the encryption-type flag in the following way:

  gcloud firestore databases restore
  --encryption-type=google-default-encryption

Restore a CMEK-protected database to the same encryption type as the backup

To restore to the same encryption type as the backup, set the encryption-type flag in the following way:

  gcloud firestore databases restore --encryption-type=use-source-encryption

Firebase CLI

Restore a CMEK-protected database to CMEK encryption

To restore to CMEK encryption, use the optional encryption-type and kms-key-name flag. If you don't specify the encryption type, the restored database will use the same encryption configuration as the backup.

firebase firestore:databases:restore \
--database DATABASE_ID \
--backup 'projects/FIRESTORE_PROJECT/locations/FIRESTORE_LOCATION/backups/BACKUP_ID' \
--encryption-type CUSTOMER_MANAGED_ENCRYPTION \
--kms-key-name projects/KMS_PROJECT/locations/KMS_LOCATION/keyRings/KMS_KEYRING_ID/cryptoKeys/KMS_KEY_ID \
--project FIRESTORE_PROJECT

Replace the following:

  • DATABASE_ID with the ID of your database
  • FIRESTORE_PROJECT with the project to use for your Firestore database
  • FIRESTORE_LOCATION with the location of your Firestore database
  • BACKUP_ID with the ID of your backup
  • KMS_PROJECT with the project that contains your CMEK key
  • KMS_LOCATION with the location that contains your CMEK key and key ring
  • KMS_KEYRING_ID with the ID of your CMEK key ring

Confirm that your restored Firestore database is CMEK-encrypted:

firebase firestore:databases:get DATABASE_ID --project FIRESTORE_PROJECT

Restore a CMEK-protected database to default encryption

To restore to Google's default encryption (non-CMEK), set the encryption-type flag in the following way:

firebase firestore:databases:restore \
--database DATABASE_ID \
--backup 'projects/FIRESTORE_PROJECT/locations/FIRESTORE_LOCATION/backups/BACKUP_ID' \
--encryption-type GOOGLE_DEFAULT_ENCRYPTION \
--project FIRESTORE_PROJECT

Replace the following:

  • DATABASE_ID with the ID of your database
  • FIRESTORE_PROJECT with the project to use for your Firestore database
  • FIRESTORE_LOCATION with the location of your Firestore database
  • BACKUP_ID with the ID of your backup

Restore a CMEK-protected database to the same encryption type as the backup

To restore to the same encryption type as the backup, set the encryption-type flag in the following way:

firebase firestore:databases:restore \
--database DATABASE_IDD \
--backup 'projects/FIRESTORE_PROJECT/locations/FIRESTORE_LOCATION/backups/BACKUP_ID' \
--encryption-type USE_SOURCE_ENCRYPTION

Replace the following:

  • DATABASE_ID with the ID of your database
  • FIRESTORE_PROJECT with the project to use for your Firestore database
  • FIRESTORE_LOCATION with the location of your Firestore database
  • BACKUP_ID with the ID of your backup

Clone a CMEK-protected database

Before you clone a CMEK-protected database:

  • Decide if you want to clone the database to CMEK encryption, to Google's default encryption (non-CMEK), or to the same encryption as the source database.
  • Prepare the key (primary-version) and the key version that you used to encrypt the source database. Enable both the key and the key version.

gcloud

Clone a CMEK-protected database to CMEK encryption

To clone to CMEK encryption, run the gcloud firestore databases clone command with the optional encryption-type and kms-key-name flags to configure the encryption type for the cloned database. If you don't specify the encryption type, the cloned database will use the same encryption configuration as the source database.

gcloud firestore databases clone \
--encryption-type=customer-managed-encryption \
--kms-key-name=KMS_KEY_NAME

Replace KMS_KEY_NAME with the name that you assigned to the key. Use the full resource name for the key in the following format:

projects/KMS_PROJECT/locations/KMS_LOCATION/keyRings/KMS_KEYRING_ID/cryptoKeys/KMS_KEY_ID

Clone a CMEK-protected database to default encryption

To clone to