Claves de Cloud KMS administradas por el cliente

De forma predeterminada, BigQuery encripta el contenido almacenado en reposo. BigQuery controla y administra esta encriptación predeterminada por ti sin que tengas que realizar ninguna acción adicional. Primero, los datos en una tabla de BigQuery se encriptan con una clave de encriptación de datos. Luego, esas claves de encriptación de datos se encriptan con la clave de encriptación de claves. Este proceso se denomina encriptación de sobre. Las claves de encriptación de claves no encriptan tus datos de modo directo, pero se usan para encriptar las claves de encriptación de datos que Google usa a fin de encriptar tus datos. Para obtener más información, consulta Cloud Key Management Service (KMS).

Si deseas controlar la encriptación por tu cuenta, puedes usar las claves de encriptación administradas por el cliente (CMEK) para BigQuery. En lugar de que Google administre las claves de encriptación de claves que protegen tus datos, tú las controlas y las administras en Cloud KMS. En este documento se proveen detalles sobre esta técnica.

Obtén más información sobre las opciones de encriptación en Google Cloud. Para obtener información específica sobre las CMEK, incluidas sus ventajas y limitaciones, consulta Claves de encriptación administradas por el cliente.

Antes de comenzar

  • Todos los recursos de datos que residen en el almacenamiento administrado de BigQuery admiten CMEK. Sin embargo, si consultas datos almacenados en una fuente de datos externa, como Cloud Storage, que tiene datos encriptados con CMEK, Cloud Storage administra la encriptación de datos. Por ejemplo, las tablas de BigLake admiten datos encriptados con CMEK en Cloud Storage.

    Las tablas BigQuery y de BigLake no admiten Claves de encriptación proporcionadas por el cliente (CSEK).

  • Decide si ejecutarás BigQuery y Cloud KMS en el mismo proyecto de Google Cloud, o si lo harás en proyectos distintos. Con el propósito de brindar documentación de ejemplo, se usa la siguiente convención:

    • PROJECT_ID: Es el ID del proyecto que ejecuta BigQuery.
    • PROJECT_NUMBER: Es el número del proyecto que ejecuta BigQuery.
    • KMS_PROJECT_ID: Es el ID del proyecto que ejecuta Cloud KMS (incluso si es el mismo proyecto que ejecuta BigQuery).
    Para obtener información sobre los ID de proyecto de Google Cloud y los números de proyecto, consulta la sección sobre cómo identificar proyectos.

  • BigQuery se habilita automáticamente en proyectos nuevos. Si usas un proyecto existente para ejecutar BigQuery, habilita la API de BigQuery.

  • En el proyecto de Google Cloud que ejecuta Cloud KMS, haz lo siguiente:

    1. Habilita la API de Cloud Key Management Service.
    2. Crea un llavero de claves y una clave como se describe en Crea claves simétricas. Crea el llavero de claves en una ubicación que coincida con la de tu conjunto de datos de BigQuery:
      • Cualquier conjunto de datos multirregional debe usar un llavero de claves multirregional desde una ubicación que coincida. Por ejemplo, un conjunto de datos en la región US debe protegerse con un llavero de claves de la región us, y un conjunto de datos en la región EU debe protegerse con un llavero de claves de la región europe.
      • Los conjuntos de datos regionales deben usar una clave regional que coincida. Por ejemplo, un conjunto de datos en la región asia-northeast1 debe protegerse con un llavero de claves de la región asia-northeast1.
      • No puedes usar la región global cuando configuras CMEK para BigQuery en la consola de Google Cloud. Sin embargo, puedes usar la región global cuando configuras CMEK para nBigQuery mediante la herramienta de línea de comandos de bq o GoogleSQL.
      Si quieres obtener más información sobre las ubicaciones compatibles con BigQuery y Cloud KMS, consulta Ubicaciones de Cloud.

Se realiza una llamada de desencriptación con Cloud KMS una vez por consulta a una tabla con encriptación de CMEK. Para obtener más información, consulta Precios de Cloud KMS.

Especificaciones de encriptación

Las claves de Cloud KMS que se usan para proteger tus datos en BigQuery son claves AES-256. Estas claves se usan como claves de encriptación de claves en BigQuery porque encriptan las claves de encriptación de datos que encriptan tus datos.

Otorga permisos de encriptación y desencriptación

A fin de proteger los datos de BigQuery con una clave CMEK, otorga permiso a la cuenta de servicio de BigQuery para encriptar y desencriptar mediante esa clave. La función de encriptador y desencriptador de CryptoKey de Cloud KMS otorga este permiso.

Asegúrate de que se haya creado la cuenta de servicio y, luego, usa la consola de Google Cloud para determinar el ID de la cuenta de servicio de BigQuery. A continuación, proporciona a la cuenta de servicio la función adecuada para encriptar y desencriptar mediante Cloud KMS.

Activa la creación de tu cuenta de servicio

En principio, tu cuenta de servicio de BigQuery no se crea cuando creas un proyecto. Para activar la creación de tu cuenta de servicio, ingresa un comando que la use, como el comando bq show --encryption_service_account o llama a la Método de la API de projects.getServiceAccount. Por ejemplo:

bq show --encryption_service_account --project_id=PROJECT_ID

Determina el ID de cuenta de servicio

El ID de la cuenta de servicio de BigQuery tiene el siguiente formato:

bq-PROJECT_NUMBER@bigquery-encryption.iam.gserviceaccount.com

Con las siguientes técnicas, se muestra cómo puedes determinar el ID de la cuenta de servicio de BigQuery para tu proyecto.

Consola

  1. Ve a la página Panel en la consola de Google Cloud.

    Ir a la página Panel

  2. Haz clic en la lista desplegable Seleccionar una opción en la parte superior de la página. En la ventana Seleccionar una opción que aparece, elige tu proyecto.

  3. El ID y el número del proyecto se muestran en la tarjeta de Información del proyecto (Project info) del panel del proyecto:

    Tarjeta de información del proyecto

  4. En la siguiente string, reemplaza PROJECT_NUMBER por el número de tu proyecto. La string nueva identifica el ID de la cuenta de servicio de BigQuery.

    bq-PROJECT_NUMBER@bigquery-encryption.iam.gserviceaccount.com
    

bq

Usa el comando bq show con la marca --encryption_service_account para determinar el ID de la cuenta de servicio:

bq show --encryption_service_account

El comando muestra el ID de la cuenta de servicio:

                  ServiceAccountID
-------------------------------------------------------------
bq-PROJECT_NUMBER@bigquery-encryption.iam.gserviceaccount.com

Asigna la función Encriptador/Desencriptador

Asigna la función de encriptador y desencriptador de CryptoKey de Cloud KMS a la cuenta de servicio del sistema de BigQuery que copiaste en tu portapapeles. Esta cuenta tiene el formato siguiente:

bq-PROJECT_NUMBER@bigquery-encryption.iam.gserviceaccount.com

Consola

  1. Abre la página Claves criptográficas en la consola de Google Cloud.

    Abrir la página Claves criptográficas

  2. Haz clic en el nombre del llavero de claves que contiene la clave.

  3. Haz clic en la casilla de verificación de la clave de encriptación a la que deseas agregar la función. Se abrirá la pestaña Permisos.

  4. Haz clic en Agregar miembro.

  5. Ingresa la dirección de correo electrónico de la cuenta de servicio, bq-PROJECT_NUMBER@bigquery-encryption.iam.gserviceaccount.com.

    • Si la cuenta de servicio ya se encuentra en la lista de miembros, es porque tiene funciones existentes. Haz clic en la lista desplegable de funciones actuales de la cuenta de servicio bq-PROJECT_NUMBER@bigquery-encryption.iam.gserviceaccount.com.
  6. Haz clic en la lista desplegable y selecciona Selecciona una función. Haz clic en Cloud KMS y, luego, en la función de Encriptador/desencriptador de CryptoKey de Cloud KMS.

  7. Haz clic en Guardar para aplicar la función a la cuenta de servicio bq-PROJECT_NUMBER@bigquery-encryption.iam.gserviceaccount.com.

gcloud

Puedes usar Google Cloud CLI para asignar la función:

gcloud kms keys add-iam-policy-binding \
--project=KMS_PROJECT_ID \
--member serviceAccount:bq-PROJECT_NUMBER@bigquery-encryption.iam.gserviceaccount.com \
--role roles/cloudkms.cryptoKeyEncrypterDecrypter \
--location=KMS_KEY_LOCATION \
--keyring=KMS_KEY_RING \
KMS_KEY

Reemplaza lo siguiente:

  • KMS_PROJECT_ID: Es el ID del proyecto de Google Cloud que ejecuta Cloud KMS.
  • PROJECT_NUMBER: Es el número del proyecto (no el ID) del proyecto de Google Cloud que ejecuta BigQuery.
  • KMS_KEY_LOCATION: Es el nombre de la ubicación de la clave de Cloud KMS.
  • KMS_KEY_RING: Es el nombre del llavero de claves de la clave de Cloud KMS.
  • KMS_KEY: Es el nombre de la clave de Cloud KMS.

ID de recurso de la clave

El ID de recurso de la clave de Cloud KMS es obligatorio para el uso de CMEK, como se muestra en los ejemplos. Esta clave distingue mayúsculas de minúsculas y tiene el siguiente formato:

projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY

Recupera el ID de recurso de la clave

  1. Abre la página Claves criptográficas en la consola de Google Cloud.

    Abrir la página Claves criptográficas

  2. Haz clic en el nombre del llavero de claves que contiene la clave.

  3. Para la clave con el ID de recurso que quieres recuperar, haz clic en Más .

  4. Haz clic en Copiar nombre del recurso. El ID de recurso de la clave se copia en el portapapeles. El ID de recurso también se conoce como el nombre del recurso.

Crea una tabla protegida por Cloud KMS

Para crear una tabla protegida por Cloud KMS, sigue estos pasos:

Consola

  1. Abre la página BigQuery en la consola de Google Cloud.

    Ir a la página de BigQuery

  2. En el panel Explorador, expande tu proyecto y selecciona un conjunto de datos.

  3. Expande la opción Acciones y haz clic en Abrir.

  4. En el panel de detalles, haz clic en Crear tabla  (Create table).

  5. En la página Crear tabla, completa la información requerida para crear una tabla vacía con una definición de esquema. Antes de hacer clic en Crear tabla, configura el tipo de encriptación y especifica la clave de Cloud KMS que se usará con la tabla:

    1. Haz clic en Opciones avanzadas.
    2. Haz clic en Clave administrada por el cliente.
    3. Selecciona la llave. Si la clave que quieres usar no aparece en la lista, ingresa el ID de recurso de la clave.
  6. Haz clic en Crear tabla.

SQL

Usa la sentencia CREATE TABLE con la opción kms_key_name:

  1. En la consola de Google Cloud, ve a la página de BigQuery.

    Ir a BigQuery

  2. En el editor de consultas, escribe la siguiente sentencia:

    CREATE TABLE DATASET_ID.TABLE_ID (
      name STRING, value INT64
    ) OPTIONS (
        kms_key_name
          = 'projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY');
    

  3. Haz clic en Ejecutar.

Si deseas obtener información sobre cómo ejecutar consultas, visita Ejecuta una consulta interactiva.

bq

Puedes usar la herramienta de línea de comandos de bq con la marca --destination_kms_key para crear la tabla. La marca --destination_kms_key especifica el ID de recurso de la clave para usar con la tabla.

Crear una tabla vacía con un esquema:

bq mk --schema name:string,value:integer -t \
--destination_kms_key projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY \
DATASET_ID.TABLE_ID

Para crear una tabla desde una consulta:

bq query --destination_table=DATASET_ID.TABLE_ID \
--destination_kms_key projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY \
"SELECT name,count FROM DATASET_ID.TABLE_ID WHERE gender = 'M' ORDER BY count DESC LIMIT 6"

Para obtener más información sobre la herramienta de línea de comandos de bq, consulta Usa la herramienta de línea de comandos de bq.

Terraform

Usa el recurso google_bigquery_table.

En el siguiente ejemplo, se crea una tabla llamada mytable y también usa los recursos google_kms_crypto_key y google_kms_key_ring para especificar una clave de Cloud Key Management Service para la tabla.

Para ejecutar este ejemplo, debes habilitar la API de Cloud Resource Manager y la API de Cloud Key Management Service.

resource "google_bigquery_dataset" "default" {
  dataset_id                      = "mydataset"
  default_partition_expiration_ms = 2592000000  # 30 days
  default_table_expiration_ms     = 31536000000 # 365 days
  description                     = "dataset description"
  location                        = "US"
  max_time_travel_hours           = 96 # 4 days

  labels = {
    billing_group = "accounting",
    pii           = "sensitive"
  }
}

resource "google_bigquery_table" "default" {
  dataset_id          = google_bigquery_dataset.default.dataset_id
  table_id            = "mytable"
  deletion_protection = false # set to "true" in production

  schema = <<EOF
[
  {
    "name": "ID",
    "type": "INT64",
    "mode": "NULLABLE",
    "description": "Item ID"
  },
  {
    "name": "Item",
    "type": "STRING",
    "mode": "NULLABLE"
  }
]
EOF

  encryption_configuration {
    kms_key_name = google_kms_crypto_key.crypto_key.id
  }

  depends_on = [google_project_iam_member.service_account_access]
}

resource "google_kms_crypto_key" "crypto_key" {
  name     = "example-key"
  key_ring = google_kms_key_ring.key_ring.id
}

resource "random_id" "default" {
  byte_length = 8
}

resource "google_kms_key_ring" "key_ring" {
  name     = "${random_id.default.hex}-example-keyring"
  location = "us"
}

# Enable the BigQuery service account to encrypt/decrypt Cloud KMS keys
data "google_project" "project" {
}

resource "google_project_iam_member" "service_account_access" {
  project = data.google_project.project.project_id
  role    = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
  member  = "serviceAccount:bq-${data.google_project.project.number}@bigquery-encryption.iam.gserviceaccount.com"
}

Para aplicar tu configuración de Terraform en un proyecto de Google Cloud, completa los pasos de las siguientes secciones.

Prepara Cloud Shell

  1. Inicia Cloud Shell
  2. Establece el proyecto de Google Cloud predeterminado en el que deseas aplicar tus configuraciones de Terraform.

    Solo necesitas ejecutar este comando una vez por proyecto y puedes ejecutarlo en cualquier directorio.

    export GOOGLE_CLOUD_PROJECT=PROJECT_ID

    Las variables de entorno se anulan si configuras valores explícitos en el archivo de configuración de Terraform.

Prepara el directorio

Cada archivo de configuración de Terraform debe tener su propio directorio (también llamado módulo raíz).

  1. En Cloud Shell, crea un directorio y un archivo nuevo dentro de ese directorio. El nombre del archivo debe tener la extensión .tf, por ejemplo, main.tf. En este instructivo, el archivo se denomina main.tf.
    mkdir DIRECTORY && cd DIRECTORY && touch main.tf
  2. Si sigues un instructivo, puedes copiar el código de muestra en cada sección o paso.

    Copia el código de muestra en el main.tf recién creado.

    De manera opcional, copia el código de GitHub. Esto se recomienda cuando el fragmento de Terraform es parte de una solución de extremo a extremo.

  3. Revisa y modifica los parámetros de muestra que se aplicarán a tu entorno.
  4. Guarda los cambios.
  5. Inicialice Terraform. Solo debes hacerlo una vez por directorio.
    terraform init

    De manera opcional, incluye la opción -upgrade para usar la última versión del proveedor de Google:

    terraform init -upgrade

Aplica los cambios

  1. Revisa la configuración y verifica que los recursos que creará o actualizará Terraform coincidan con tus expectativas:
    terraform plan

    Corrige la configuración según sea necesario.

  2. Para aplicar la configuración de Terraform, ejecuta el siguiente comando y, luego, escribe yes cuando se te solicite:
    terraform apply

    Espera hasta que Terraform muestre el mensaje “¡Aplicación completa!”.

  3. Abre tu proyecto de Google Cloud para ver los resultados. En la consola de Google Cloud, navega a tus recursos en la IU para asegurarte de que Terraform los haya creado o actualizado.

Go

Antes de probar este ejemplo, sigue las instrucciones de configuración para Go incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Go.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

import (
	"context"
	"fmt"

	"cloud.google.com/go/bigquery"
)

// createTableWithCMEK demonstrates creating a table protected with a customer managed encryption key.
func createTableWithCMEK(projectID, datasetID, tableID string) error {
	// projectID := "my-project-id"
	// datasetID := "mydatasetid"
	// tableID := "mytableid"
	ctx := context.Background()

	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	tableRef := client.Dataset(datasetID).Table(tableID)
	meta := &bigquery.TableMetadata{
		EncryptionConfig: &bigquery.EncryptionConfig{
			// TODO: Replace this key with a key you have created in Cloud KMS.
			KMSKeyName: "projects/cloud-samples-tests/locations/us/keyRings/test/cryptoKeys/test",
		},
	}
	if err := tableRef.Create(ctx, meta); err != nil {
		return err
	}
	return nil
}

Java

Antes de probar este ejemplo, sigue las instrucciones de configuración para Java incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Java.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.EncryptionConfiguration;
import com.google.cloud.bigquery.Field;
import com.google.cloud.bigquery.Schema;
import com.google.cloud.bigquery.StandardSQLTypeName;
import com.google.cloud.bigquery.StandardTableDefinition;
import com.google.cloud.bigquery.TableDefinition;
import com.google.cloud.bigquery.TableId;
import com.google.cloud.bigquery.TableInfo;

// Sample to create a cmek table
public class CreateTableCMEK {

  public static void runCreateTableCMEK() {
    // TODO(developer): Replace these variables before running the sample.
    String datasetName = "MY_DATASET_NAME";
    String tableName = "MY_TABLE_NAME";
    String kmsKeyName = "MY_KEY_NAME";
    Schema schema =
        Schema.of(
            Field.of("stringField", StandardSQLTypeName.STRING),
            Field.of("booleanField", StandardSQLTypeName.BOOL));
    // i.e. projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{cryptoKey}
    EncryptionConfiguration encryption =
        EncryptionConfiguration.newBuilder().setKmsKeyName(kmsKeyName).build();
    createTableCMEK(datasetName, tableName, schema, encryption);
  }

  public static void createTableCMEK(
      String datasetName, String tableName, Schema schema, EncryptionConfiguration configuration) {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      TableId tableId = TableId.of(datasetName, tableName);
      TableDefinition tableDefinition = StandardTableDefinition.of(schema);
      TableInfo tableInfo =
          TableInfo.newBuilder(tableId, tableDefinition)
              .setEncryptionConfiguration(configuration)
              .build();

      bigquery.create(tableInfo);
      System.out.println("Table cmek created successfully");
    } catch (BigQueryException e) {
      System.out.println("Table cmek was not created. \n" + e.toString());
    }
  }
}

Python

Antes de probar este ejemplo, sigue las instrucciones de configuración para Python incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Python.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

Para proteger una tabla nueva con una clave de encriptación administrada por el cliente, configura la propiedad Table.encryption_configuration como un objeto EncryptionConfiguration antes de crear la tabla.
from google.cloud import bigquery

client = bigquery.Client()

# TODO(dev): Change table_id to the full name of the table you want to create.
table_id = "your-project.your_dataset.your_table_name"

# Set the encryption key to use for the table.
# TODO: Replace this key with a key you have created in Cloud KMS.
kms_key_name = "projects/your-project/locations/us/keyRings/test/cryptoKeys/test"

table = bigquery.Table(table_id)
table.encryption_configuration = bigquery.EncryptionConfiguration(
    kms_key_name=kms_key_name
)
table = client.create_table(table)  # API request

print(f"Created {table_id}.")
print(f"Key: {table.encryption_configuration.kms_key_name}.")

Consulta una tabla protegida por una clave de Cloud KMS

No se necesitan arreglos especiales a fin de consultar una tabla protegida por Cloud KMS. BigQuery almacena el nombre de la clave que se usó para encriptar el contenido de la tabla y la usará cuando se consulte una tabla que protege Cloud KMS.

Todas las herramientas existentes, la consola de BigQuery y la herramienta de línea de comandos de bq se ejecutan de la misma manera que con las tablas encriptadas de forma predeterminada, siempre que BigQuery tenga acceso a la clave de Cloud KMS que se usó para encriptar el contenido de la tabla.

Protege resultados de consultas con la clave de Cloud KMS

De forma predeterminada, los resultados de la consulta se almacenan en una tabla temporal encriptada con una clave administrada por Google. Si, en cambio, usas una clave de Cloud KMS para encriptar los resultados de la consulta, selecciona una de las siguientes opciones:

Consola

  1. Abre la página BigQuery en la consola de Google Cloud.

    Ir a la página de BigQuery

  2. Haz clic en Redactar consulta nueva.

  3. Ingresa una consulta válida de GoogleSQL en el área de texto de la consulta.

  4. Haz clic en Más, luego, en Configuración de consultas y, por último, en Opciones avanzadas.

  5. Selecciona Customer-managed encryption.

  6. Selecciona la llave. Si la clave que quieres usar no aparece en la lista, ingresa el ID de recurso de la clave.

  7. Haz clic en Guardar.

  8. Haz clic en Ejecutar.

bq

Especifica la marca --destination_kms_key para proteger la tabla de destino o los resultados de las consultas (si usas una tabla temporal) con tu clave de Cloud KMS. La marca --destination_kms_key especifica el ID de recurso de la clave que se debe usar con la tabla de destino o la tabla resultante.

De forma opcional, puedes usar la marca --destination_table para especificar el destino de los resultados de la consulta. Si --destination_table no se usa, los resultados de la consulta se escriben en una tabla temporal.

Para consultar una tabla, sigue estos pasos:

bq query \
--destination_table=DATASET_ID.TABLE_ID \
--destination_kms_key projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY \
"SELECT name,count FROM DATASET_ID.TABLE_ID WHERE gender = 'M' ORDER BY count DESC LIMIT 6"

Para obtener más información sobre la herramienta de línea de comandos de bq, consulta Usa la herramienta de línea de comandos de bq.

Go

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/bigquery"
	"google.golang.org/api/iterator"
)

// queryWithDestinationCMEK demonstrates saving query results to a destination table and protecting those results
// by specifying a customer managed encryption key.
func queryWithDestinationCMEK(w io.Writer, projectID, dstDatasetID, dstTableID string) error {
	// projectID := "my-project-id"
	// datasetID := "mydataset"
	// tableID := "mytable"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	q := client.Query("SELECT 17 as my_col")
	q.Location = "US" // Location must match the dataset(s) referenced in query.
	q.QueryConfig.Dst = client.Dataset(dstDatasetID).Table(dstTableID)
	q.DestinationEncryptionConfig = &bigquery.EncryptionConfig{
		// TODO: Replace this key with a key you have created in Cloud KMS.
		KMSKeyName: "projects/cloud-samples-tests/locations/us-central1/keyRings/test/cryptoKeys/test",
	}
	// Run the query and print results when the query job is completed.
	job, err := q.Run(ctx)
	if err != nil {
		return err
	}
	status, err := job.Wait(ctx)
	if err != nil {
		return err
	}
	if err := status.Err(); err != nil {
		return err
	}
	it, err := job.Read(ctx)
	for {
		var row []bigquery.Value
		err := it.Next(&row)
		if err == iterator.Done {
			break
		}
		if err != nil {
			return err
		}
		fmt.Fprintln(w, row)
	}
	return nil
}

Java

Antes de probar este ejemplo, sigue las instrucciones de configuración para Java incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Java.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

Para proteger una tabla nueva con una clave de encriptación administrada por el cliente, configura la propiedad Table.encryption_configuration como un objeto EncryptionConfiguration antes de crear la tabla.
import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.EncryptionConfiguration;
import com.google.cloud.bigquery.QueryJobConfiguration;
import com.google.cloud.bigquery.TableResult;

// Sample to query on destination table with encryption key
public class QueryDestinationTableCMEK {

  public static void runQueryDestinationTableCMEK() {
    // TODO(developer): Replace these variables before running the sample.
    String datasetName = "MY_DATASET_NAME";
    String tableName = "MY_TABLE_NAME";
    String kmsKeyName = "MY_KMS_KEY_NAME";
    String query =
        String.format("SELECT stringField, booleanField FROM %s.%s", datasetName, tableName);
    EncryptionConfiguration encryption =
        EncryptionConfiguration.newBuilder().setKmsKeyName(kmsKeyName).build();
    queryDestinationTableCMEK(query, encryption);
  }

  public static void queryDestinationTableCMEK(String query, EncryptionConfiguration encryption) {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      QueryJobConfiguration config =
          QueryJobConfiguration.newBuilder(query)
              // Set the encryption key to use for the destination.
              .setDestinationEncryptionConfiguration(encryption)
              .build();

      TableResult results = bigquery.query(config);

      results
          .iterateAll()
          .forEach(row -> row.forEach(val -> System.out.printf("%s,", val.toString())));
      System.out.println("Query performed successfully with encryption key.");
    } catch (BigQueryException | InterruptedException e) {
      System.out.println("Query not performed \n" + e.toString());
    }
  }
}

Python

from google.cloud import bigquery

# Construct a BigQuery client object.
client = bigquery.Client()

# TODO(developer): Set table_id to the ID of the destination table.
# table_id = "your-project.your_dataset.your_table_name"

# Set the encryption key to use for the destination.
# TODO(developer): Replace this key with a key you have created in KMS.
# kms_key_name = "projects/{}/locations/{}/keyRings/{}/cryptoKeys/{}".format(
#     your-project, location, your-ring, your-key
# )

job_config = bigquery.QueryJobConfig(
    destination=table_id,
    destination_encryption_configuration=bigquery.EncryptionConfiguration(
        kms_key_name=kms_key_name
    ),
)

# Start the query, passing in the extra configuration.
query_job = client.query(
    "SELECT 17 AS my_col;", job_config=job_config
)  # Make an API request.
query_job.result()  # Wait for the job to complete.

table = client.get_table(table_id)  # Make an API request.
if table.encryption_configuration.kms_key_name == kms_key_name:
    print("The destination table is written using the encryption configuration")

Carga una tabla protegida por Cloud KMS

Para cargar un archivo de datos en una tabla protegida por Cloud KMS, sigue estos pasos:

Consola

Especifica la clave cuando cargues una tabla de destino del trabajo de carga para protegerla con una clave de encriptación administrada por el cliente.

  1. Abre la página BigQuery en la consola de Google Cloud.

    Ir a la página de BigQuery

  2. En el panel Explorador, expande tu proyecto y selecciona un conjunto de datos.

  3. En el panel de detalles, haz clic en Crear tabla (Create table).

  4. Ingresa las opciones que deseas usar para cargar la tabla, pero antes de hacer clic en Crear tabla, haz clic en Opciones avanzadas (Advanced options).

  5. En Encriptación, selecciona Clave administrada por el cliente.

  6. Haz clic en la lista desplegable Selecciona una clave administrada por el cliente (Select a customer-managed key) y selecciona la clave que deseas usar. Si no hay claves disponibles, ingresa un ID de recurso de la clave.

    Opciones avanzadas

  7. Haz clic en Crear tabla.

bq

Para proteger una tabla de destino del trabajo de carga con una clave de encriptación administrada por el cliente, configura la marca --destination_kms_key.

bq --location=LOCATION load \
--autodetect \
--source_format=FORMAT \
--destination_kms_key projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY \
DATASET.TABLE \
path_to_source
Por ejemplo:
bq load \
--autodetect \
--source_format=NEWLINE_DELIMITED_JSON \
--destination_kms_key projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY \
test2.table4 \
gs://cloud-samples-data/bigquery/us-states/us-states.json

Go

import (
	"context"
	"fmt"

	"cloud.google.com/go/bigquery"
)

// importJSONWithCMEK demonstrates loading newline-delimited JSON from Cloud Storage,
// and protecting the data with a customer-managed encryption key.
func importJSONWithCMEK(projectID, datasetID, tableID string) error {
	// projectID := "my-project-id"
	// datasetID := "mydataset"
	// tableID := "mytable"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	gcsRef := bigquery.NewGCSReference("gs://cloud-samples-data/bigquery/us-states/us-states.json")
	gcsRef.SourceFormat = bigquery.JSON
	gcsRef.AutoDetect = true
	loader := client.Dataset(datasetID).Table(tableID).LoaderFrom(gcsRef)
	loader.WriteDisposition = bigquery.WriteEmpty
	loader.DestinationEncryptionConfig = &bigquery.EncryptionConfig{
		// TODO: Replace this key with a key you have created in KMS.
		KMSKeyName: "projects/cloud-samples-tests/locations/us-central1/keyRings/test/cryptoKeys/test",
	}

	job, err := loader.Run(ctx)
	if err != nil {
		return err
	}
	status, err := job.Wait(ctx)
	if err != nil {
		return err
	}

	if status.Err() != nil {
		return fmt.Errorf("job completed with error: %v", status.Err())
	}

	return nil
}

Java

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.EncryptionConfiguration;
import com.google.cloud.bigquery.FormatOptions;
import com.google.cloud.bigquery.Job;
import com.google.cloud.bigquery.JobInfo;
import com.google.cloud.bigquery.LoadJobConfiguration;
import com.google.cloud.bigquery.TableId;

// Sample to load JSON data with configuration key from Cloud Storage into a new BigQuery table
public class LoadJsonFromGCSCMEK {

  public static void runLoadJsonFromGCSCMEK() {
    // TODO(developer): Replace these variables before running the sample.
    String datasetName = "MY_DATASET_NAME";
    String tableName = "MY_TABLE_NAME";
    String kmsKeyName = "MY_KMS_KEY_NAME";
    String sourceUri = "gs://cloud-samples-data/bigquery/us-states/us-states.json";
    // i.e. projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{cryptoKey}
    EncryptionConfiguration encryption =
        EncryptionConfiguration.newBuilder().setKmsKeyName(kmsKeyName).build();
    loadJsonFromGCSCMEK(datasetName, tableName, sourceUri, encryption);
  }

  public static void loadJsonFromGCSCMEK(
      String datasetName, String tableName, String sourceUri, EncryptionConfiguration encryption) {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      TableId tableId = TableId.of(datasetName, tableName);
      LoadJobConfiguration loadConfig =
          LoadJobConfiguration.newBuilder(tableId, sourceUri)
              // Set the encryption key to use for the destination.
              .setDestinationEncryptionConfiguration(encryption)
              .setFormatOptions(FormatOptions.json())
              .setAutodetect(true)
              .build();

      // Load data from a GCS JSON file into the table
      Job job = bigquery.create(JobInfo.of(loadConfig));
      // Blocks until this load table job completes its execution, either failing or succeeding.
      job = job.waitFor();
      if (job.isDone()) {
        System.out.println("Table loaded succesfully from GCS with configuration key");
      } else {
        System.out.println(
            "BigQuery was unable to load into the table due to an error:"
                + job.getStatus().getError());
      }
    } catch (BigQueryException | InterruptedException e) {
      System.out.println("Column not added during load append \n" + e.toString());
    }
  }
}

Python

Para proteger una tabla de destino del trabajo de carga con una clave de encriptación administrada por el cliente, configura la propiedad LoadJobConfig.destination_encryption_configuration como una EncryptionConfiguration y carga la tabla.

from google.cloud import bigquery

# Construct a BigQuery client object.
client = bigquery.Client()

# TODO(developer): Set table_id to the ID of the table to create.
# table_id = "your-project.your_dataset.your_table_name

# Set the encryption key to use for the destination.
# TODO: Replace this key with a key you have created in KMS.
# kms_key_name = "projects/{}/locations/{}/keyRings/{}/cryptoKeys/{}".format(
#     "cloud-samples-tests", "us", "test", "test"
# )

job_config = bigquery.LoadJobConfig(
    autodetect=True,
    source_format=bigquery.SourceFormat.NEWLINE_DELIMITED_JSON,
    destination_encryption_configuration=bigquery.EncryptionConfiguration(
        kms_key_name=kms_key_name
    ),
)

uri = "gs://cloud-samples-data/bigquery/us-states/us-states.json"

load_job = client.load_table_from_uri(
    uri,
    table_id,
    location="US",  # Must match the destination dataset location.
    job_config=job_config,
)  # Make an API request.

assert load_job.job_type == "load"

load_job.result()  # Waits for the job to complete.

assert load_job.state == "DONE"
table = client.get_table(table_id)

if table.encryption_configuration.kms_key_name == kms_key_name:
    print("A table loaded with encryption configuration key")

Transmite en una tabla protegida por Cloud KMS

Puedes transmitir datos a tu tabla de BigQuery protegida por CMEK sin especificar ningún parámetro adicional. Ten en cuenta que estos datos se encriptaron con tu clave de Cloud KMS en el búfer, así como en la ubicación final. Antes de usar la transmisión con una tabla de CMEK, revisa los requisitos sobre la disponibilidad y accesibilidad de la clave.

Para obtener más información sobre la transmisión, consulta Transmite datos a BigQuery.

Cambia una tabla de encriptación predeterminada a protección de Cloud KMS

bq

Puedes usar el comando bq cp con la marca --destination_kms_key para copiar una tabla protegida por encriptación predeterminada en una tabla nueva o en la tabla original, protegida por Cloud KMS. La marca --destination_kms_key especifica el ID de recurso de la clave que se debe usar con la tabla de destino.

Para copiar una tabla con encriptación predeterminada a una tabla nueva con protección de Cloud KMS, usa un comando como este:

bq cp \
--destination_kms_key projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY \
SOURCE_DATASET_ID.SOURCE_TABLE_ID DESTINATION_DATASET_ID.DESTINATION_TABLE_ID

Si quieres copiar una tabla con encriptación predeterminada a la misma tabla con la protección de Cloud KMS, usa un comando como este:

bq cp -f \
--destination_kms_key projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY \
DATASET_ID.TABLE_ID DATASET_ID.TABLE_ID

Si deseas cambiar la protección de una tabla de Cloud KMS a la encriptación predeterminada, copia el archivo a sí mismo y ejecuta bq cp sin la marca --destination_kms_key.

Para obtener más información sobre la herramienta de línea de comandos de bq, consulta Usa la herramienta de línea de comandos de bq.

Go

import (
	"context"
	"fmt"

	"cloud.google.com/go/bigquery"
)

// copyTableWithCMEK demonstrates creating a copy of a table and ensuring the copied data is
// protected with a customer managed encryption key.
func copyTableWithCMEK(projectID, datasetID, tableID string) error {
	// projectID := "my-project-id"
	// datasetID := "mydataset"
	// tableID := "mytable"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	srcTable := client.DatasetInProject("bigquery-public-data", "samples").Table("shakespeare")
	copier := client.Dataset(datasetID).Table(tableID).CopierFrom(srcTable)
	copier.DestinationEncryptionConfig = &bigquery.EncryptionConfig{
		// TODO: Replace this key with a key you have created in Cloud KMS.
		KMSKeyName: "projects/cloud-samples-tests/locations/us-central1/keyRings/test/cryptoKeys/test",
	}
	job, err := copier.Run(ctx)
	if err != nil {
		return err
	}
	status, err := job.Wait(ctx)
	if err != nil {
		return err
	}
	if err := status.Err(); err != nil {
		return err
	}
	return nil
}

Java

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.CopyJobConfiguration;
import com.google.cloud.bigquery.EncryptionConfiguration;
import com.google.cloud.bigquery.Job;
import com.google.cloud.bigquery.JobInfo;
import com.google.cloud.bigquery.TableId;

// Sample to copy a cmek table
public class CopyTableCMEK {

  public static void runCopyTableCMEK() {
    // TODO(developer): Replace these variables before running the sample.
    String destinationDatasetName = "MY_DESTINATION_DATASET_NAME";
    String destinationTableId = "MY_DESTINATION_TABLE_NAME";
    String sourceDatasetName = "MY_SOURCE_DATASET_NAME";
    String sourceTableId = "MY_SOURCE_TABLE_NAME";
    String kmsKeyName = "MY_KMS_KEY_NAME";
    EncryptionConfiguration encryption =
        EncryptionConfiguration.newBuilder().setKmsKeyName(kmsKeyName).build();
    copyTableCMEK(
        sourceDatasetName, sourceTableId, destinationDatasetName, destinationTableId, encryption);
  }

  public static void copyTableCMEK(
      String sourceDatasetName,
      String sourceTableId,
      String destinationDatasetName,
      String destinationTableId,
      EncryptionConfiguration encryption) {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      TableId sourceTable = TableId.of(sourceDatasetName, sourceTableId);
      TableId destinationTable = TableId.of(destinationDatasetName, destinationTableId);

      // For more information on CopyJobConfiguration see:
      // https://googleapis.dev/java/google-cloud-clients/latest/com/google/cloud/bigquery/JobConfiguration.html
      CopyJobConfiguration configuration =
          CopyJobConfiguration.newBuilder(destinationTable, sourceTable)
              .setDestinationEncryptionConfiguration(encryption)
              .build();

      // For more information on Job see:
      // https://googleapis.dev/java/google-cloud-clients/latest/index.html?com/google/cloud/bigquery/package-summary.html
      Job job = bigquery.create(JobInfo.of(configuration));

      // Blocks until this job completes its execution, either failing or succeeding.
      Job completedJob = job.waitFor();
      if (completedJob == null) {
        System.out.println("Job not executed since it no longer exists.");
        return;
      } else if (completedJob.getStatus().getError() != null) {
        System.out.println(
            "BigQuery was unable to copy table due to an error: \n" + job.getStatus().getError());
        return;
      }
      System.out.println("Table cmek copied successfully.");
    } catch (BigQueryException | InterruptedException e) {
      System.out.println("Table cmek copying job was interrupted. \n" + e.toString());
    }
  }
}

Python

Antes de probar este ejemplo, sigue las instrucciones de configuración para Python incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Python.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

Para proteger el destino de una copia de tabla con una clave de encriptación administrada por el cliente, configura la propiedad QueryJobConfig.destination_encryption_configuration como una EncryptionConfiguration y copia la tabla.

from google.cloud import bigquery

# Construct a BigQuery client object.
client = bigquery.Client()

# TODO(developer): Set dest_table_id to the ID of the destination table.
# dest_table_id = "your-project.your_dataset.your_table_name"

# TODO(developer): Set orig_table_id to the ID of the original table.
# orig_table_id = "your-project.your_dataset.your_table_name"

# Set the encryption key to use for the destination.
# TODO(developer): Replace this key with a key you have created in KMS.
# kms_key_name = "projects/{}/locations/{}/keyRings/{}/cryptoKeys/{}".format(
#     your-project, location, your-ring, your-key
# )

job_config = bigquery.CopyJobConfig(
    destination_encryption_configuration=bigquery.EncryptionConfiguration(
        kms_key_name=kms_key_name
    )
)
job = client.copy_table(orig_table_id, dest_table_id, job_config=job_config)
job.result()  # Wait for the job to complete.

dest_table = client.get_table(dest_table_id)  # Make an API request.
if dest_table.encryption_configuration.kms_key_name == kms_key_name:
    print("A copy of the table created")

Determina si una tabla está protegida por Cloud KMS

  1. En la consola de Google Cloud, haz clic en la flecha azul a la izquierda de tu conjunto de datos para expandirlo o haz doble clic sobre el nombre del conjunto de datos. Esto muestra las tablas y vistas en el conjunto de datos.

  2. Haz clic en el nombre de la tabla.

  3. Haz clic en Detalles. En la página Detalles de la tabla, se muestra la descripción y la información de la tabla.

  4. Si la tabla está protegida por Cloud KMS, el campo Customer-Managed Encryption Key mostrará el ID de recurso de la clave.

    Tabla protegida

Cambia la clave de Cloud KMS de una tabla de BigQuery

Si deseas cambiar la clave de Cloud KMS de una tabla existente protegida con CMEK, puedes ejecutar una consulta ALTER TABLE, usar la API o usar la herramienta de línea de comandos de bq. Hay dos maneras de modificar la clave de Cloud KMS mediante la API y la herramienta de línea de comandos de bq: update o cp.

Si usas update, puedes cambiar la clave de Cloud KMS que se usa para una tabla protegida con CMEK.

Si usas cp, puedes cambiar la clave de Cloud KMS que se usa para una tabla protegida con CMEK, cambiar una tabla de la encriptación predeterminada a la protección con CMEK o cambiar una tabla protegida con CMEK a la encriptación predeterminada.

Una ventaja de update es que es más rápido que cp y te permite usar decoradores de tabla.

SQL

Usa la sentencia ALTER TABLE SET OPTIONS para actualizar el campo kms_key_name de una tabla:

  1. En la consola de Google Cloud, ve a la página de BigQuery.

    Ir a BigQuery

  2. En el editor de consultas, escribe la siguiente sentencia:

    ALTER TABLE DATASET_ID.mytable
    SET OPTIONS (
      kms_key_name
        = 'projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY');
    

  3. Haz clic en Ejecutar.

Si deseas obtener información sobre cómo ejecutar consultas, visita Ejecuta una consulta interactiva.

bq

Puedes usar el comando bq cp con la marca --destination_kms_key para cambiar la clave de una tabla que tiene protección de Cloud KMS. La marca --destination_kms_key especifica el ID de recurso de la clave que se debe usar con la tabla.

bq update \
--destination_kms_key projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY \
-t DATASET_ID.TABLE_ID

Go

import (
	"context"
	"fmt"

	"cloud.google.com/go/bigquery"
)

// updateTableChangeCMEK demonstrates how to change the customer managed encryption key that protects a table.
func updateTableChangeCMEK(projectID, datasetID, tableID string) error {
	// projectID := "my-project-id"
	// datasetID := "mydatasetid"
	// tableID := "mytableid"
	ctx := context.Background()

	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	tableRef := client.Dataset(datasetID).Table(tableID)
	meta, err := tableRef.Metadata(ctx)
	if err != nil {
		return err
	}
	update := bigquery.TableMetadataToUpdate{
		EncryptionConfig: &bigquery.EncryptionConfig{
			// TODO: Replace this key with a key you have created in Cloud KMS.
			KMSKeyName: "projects/cloud-samples-tests/locations/us-central1/keyRings/test/cryptoKeys/otherkey",
		},
	}
	if _, err := tableRef.Update(ctx, update, meta.ETag); err != nil {
		return err
	}
	return nil
}

Java

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.EncryptionConfiguration;
import com.google.cloud.bigquery.Table;
import com.google.cloud.bigquery.TableId;

// Sample to update a cmek table
public class UpdateTableCMEK {

  public static void runUpdateTableCMEK() {
    // TODO(developer): Replace these variables before running the sample.
    String datasetName = "MY_DATASET_NAME";
    String tableName = "MY_TABLE_NAME";
    String kmsKeyName = "MY_KEY_NAME";
    // Set a new encryption key to use for the destination.
    // i.e. projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{cryptoKey}
    EncryptionConfiguration encryption =
        EncryptionConfiguration.newBuilder().setKmsKeyName(kmsKeyName).build();
    updateTableCMEK(datasetName, tableName, encryption);
  }

  public static void updateTableCMEK(
      String datasetName, String tableName, EncryptionConfiguration encryption) {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      Table table = bigquery.getTable(TableId.of(datasetName, tableName));
      bigquery.update(table.toBuilder().setEncryptionConfiguration(encryption).build());
      System.out.println("Table cmek updated successfully");
    } catch (BigQueryException e) {
      System.out.println("Table cmek was not updated. \n" + e.toString());
    }
  }
}

Python

Para cambiar la clave de encriptación administrada por el cliente de una tabla, cambia la propiedad Table.encryption_configuration a un objeto EncryptionConfiguration nuevo y actualiza la tabla.

# from google.cloud import bigquery
# client = bigquery.Client()

assert table.encryption_configuration.kms_key_name == original_kms_key_name

# Set a new encryption key to use for the destination.
# TODO: Replace this key with a key you have created in KMS.
updated_kms_key_name = (
    "projects/cloud-samples-tests/locations/us/keyRings/test/cryptoKeys/otherkey"
)
table.encryption_configuration = bigquery.EncryptionConfiguration(
    kms_key_name=updated_kms_key_name
)

table = client.update_table(table, ["encryption_configuration"])  # API request

assert table.encryption_configuration.kms_key_name == updated_kms_key_name
assert original_kms_key_name != updated_kms_key_name

Configura una clave predeterminada para el conjunto de datos

Puedes configurar una clave de Cloud KMS predeterminada para todo el conjunto de datos que se aplicará a todas las tablas recién creadas dentro de este, a menos que se especifique una clave de Cloud KMS diferente cuando se crea la tabla. La clave predeterminada no se aplica a las tablas existentes. Cambiar la clave predeterminada no modifica las tablas existentes y solo se aplica a las tablas nuevas creadas después del cambio.

Puedes aplicar, cambiar o quitar una clave predeterminada del conjunto de datos si realizas lo siguiente:

  • Especificas la clave predeterminada en el campo EncryptionConfiguration.kmsKeyName cuando llames a los métodos datasets.insert o datasets.patch

  • Especificar la clave predeterminada en la marca --default_kms_key cuando ejecutes el comando bq mk --dataset.

    bq mk \
    --default_kms_key projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY \
    --dataset DATASET_ID
    
    bq update \
    --default_kms_key projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY \
    --dataset DATASET_ID
    

Establece una clave predeterminada del proyecto

Puedes configurar una clave de Cloud KMS predeterminada para todo el proyecto que se aplique a todos los resultados de la consulta y a las tablas recién creadas en el proyecto, a menos que especifiques una clave de Cloud KMS diferente. La clave predeterminada no se aplica a las tablas existentes. Cambiar la clave predeterminada no modifica las tablas existentes y solo se aplica a las tablas nuevas creadas después del cambio.

SQL

Usa la sentencia ALTER PROJECT SET OPTIONS para actualizar el campo default_kms_key_name de un proyecto: Puedes encontrar el nombre del recurso de la clave en la página de Cloud KMS.

  1. En la consola de Google Cloud, ve a la página de BigQuery.

    Ir a BigQuery

  2. En el editor de consultas, escribe la siguiente sentencia:

    ALTER PROJECT PROJECT_ID
    SET OPTIONS (
      region-us.default_kms_key_name
        = 'projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY');
    

  3. Haz clic en Ejecutar.

Si deseas obtener información sobre cómo ejecutar consultas, visita Ejecuta una consulta interactiva.

bq

Puedes usar el comando bq para ejecutar una sentencia ALTER PROJECT SET OPTIONS a fin de actualizar el campo default_kms_key_name de un proyecto:

bq query --nouse_legacy_sql \
  'ALTER PROJECT PROJECT_ID
  SET OPTIONS (
  `region-us.default_kms_key_name`
    ="projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY");'

Usa CMEK para proteger los modelos de BigQuery ML

BigQuery ML es compatible con CMEK. Junto con la encriptación predeterminada proporcionada por BigQuery, puedes usar tus propias claves de Cloud Key Management Service para encriptar modelos de aprendizaje automático, incluidos los modelos importados de TensorFlow.

Crea un modelo encriptado con una clave de Cloud KMS

Para crear un modelo encriptado, usa la sentencia CREATE MODEL y especifica KMS_KEY_NAME en las opciones de entrenamiento:

    CREATE MODEL my_dataset.my_model
    OPTIONS(
      model_type='linear_reg',
      input_label_cols=['your_label'],
      kms_key_name='projects/my_project/locations/my_location/keyRings/my_ring/cryptoKeys/my_key')
    AS SELECT * FROM my_dataset.my_data

La misma sintaxis también se aplica a los modelos importados de TensorFlow:

    CREATE MODEL my_dataset.my_model
    OPTIONS(
      model_type='tensorflow',
      path='gs://bucket/path/to/saved_model/*',
      kms_key_name='projects/my_project/locations/my_location/keyRings/my_ring/cryptoKeys/my_key')
    AS SELECT * FROM my_dataset.my_data

Limitaciones

Las claves de encriptación administradas por el cliente tienen las siguientes restricciones cuando se encriptan modelos de aprendizaje automático:

Cambia un modelo de encriptación predeterminada a protección de Cloud KMS

Puedes usar el comando bq cp con la marca --destination_kms_key para copiar un modelo protegido por la encriptación predeterminada en un modelo nuevo protegido por Cloud KMS. Como alternativa, puedes usar el comando bq cp con la marca -f para reemplazar un modelo protegido por la encriptación predeterminada y actualizarlo para usar la protección de Cloud KMS en su lugar. La marca --destination_kms_key especifica el ID de recurso de la clave que se debe usar con el modelo de destino.

Para copiar un modelo que tiene encriptación predeterminada a un modelo nuevo con protección de Cloud KMS, usa un comando como este:

bq cp \
--destination_kms_key projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY \
SOURCE_DATASET_ID.SOURCE_MODEL_ID DESTINATION_DATASET_ID.DESTINATION_MODEL_ID

Para reemplazar un modelo que tiene encriptación predeterminada en el mismo modelo con la protección de Cloud KMS, sigue estos pasos:

bq cp -f \
--destination_kms_key projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY \
DATASET_ID.MODEL_ID DATASET_ID.MODEL_ID

Para cambiar un modelo de la protección de Cloud KMS a la encriptación predeterminada, haz lo siguiente:

bq cp -f \
DATASET_ID.MODEL_ID DATASET_ID.MODEL_ID

Para obtener más información sobre la herramienta de línea de comandos de bq, consulta Usa la herramienta de línea de comandos de bq.

Determina si Cloud KMS protege un modelo

Usa el comando bq show para ver si una clave de Cloud KMS protege un modelo. La clave de encriptación está en el campo kmsKeyName.

bq show -m my_dataset.my_model

También puedes usar la consola de Google Cloud a fin de encontrar la clave de Cloud KMS para un modelo encriptado. La información de CMEK se encuentra en el campo Clave administrada por el cliente en la sección Detalles del modelo del panel Detalles del modelo.

Cambia la clave de Cloud KMS para un modelo encriptado

Usa el comando bq update con la marca --destination_kms_key para cambiar la clave de una tabla protegida por Cloud KMS:

bq update --destination_kms_key \
projects/my_project/locations/my_location/keyRings/my_ring/cryptoKeys/my_key \
-t my_dataset.my_model

Usa claves de proyecto o conjunto de datos predeterminadas

Si tienes una clave de Cloud KMS predeterminada establecida a nivel de proyecto o de conjunto de datos, BigQuery ML usa esta clave de forma automática cuando crea modelos. Usa la sentencia CREATE MODEL para especificar una clave diferente a fin de encriptar el modelo si no deseas usar la clave predeterminada.

Usa funciones de BigQuery ML con modelos encriptados

Puedes usar todas las funciones AA de BigQuery con un modelo encriptado sin especificar una clave de encriptación.

Usa CMEK para proteger la API de BigQuery Connection

Para las conexiones de Cloud SQL, puedes proteger las credenciales de la API de conexión de BigQuery mediante CMEK.

Para obtener más información sobre cómo crear una conexión protegida con CMEK, consulta Crea conexiones de Cloud SQL.

Quita a la clave de Cloud KMS el acceso a BigQuery

Puedes quitar el acceso de BigQuery a la clave de Cloud KMS en cualquier momento si revocas el permiso de Identity and Access Management (IAM) de esa clave.

Si BigQuery pierde acceso a la clave de Cloud KMS, la experiencia del usuario puede verse afectada de manera significativa, y es posible que se pierdan datos:

  • Ya no se podrá acceder a los datos de estas tablas protegidas con CMEK. Los comandos query, cp, extract y tabledata.list fallarán.

  • No se podrán agregar datos nuevos a estas tablas protegidas por CMEK.

  • Después de otorgar el acceso otra vez, el rendimiento de las consultas a estas tablas queda degradado durante varios días.

Controla el uso de CMEK con la política de la organización

BigQuery se integra a las restricciones de las políticas de la organización con CMEK para que puedas especificar los requisitos de cumplimiento de encriptación para los recursos de BigQuery en tu organización.

Esta integración te permite hacer lo siguiente:

  • Requerir CMEK para todos los recursos de BigQuery de un proyecto.

  • Restringe qué claves de Cloud KMS se pueden usar para proteger los recursos en un proyecto.

Requerir CMEK para todos los recursos

Una política común es requerir que las CMEK se usen para proteger todos los recursos en un conjunto específico de proyectos. Puedes usar la restricción constraints/gcp.restrictNonCmekServices para aplicar esta política en BigQuery.

Si se configura, esta política de la organización causará que fallen todas las solicitudes de creación de recursos sin una clave especificada de Cloud KMS.

Después de establecer esta política, se aplica solo a los recursos nuevos del proyecto. Todos los recursos existentes sin las claves de Cloud KMS establecidas seguirán existiendo y se podrá acceder a ellos sin problemas.

Consola

  1. Abre la página Políticas de la organización.

    Ir a Políticas de la organización

  2. En el campo Filtro, ingresa constraints/gcp.restrictNonCmekServices y, luego, haz clic en Restringir los servicios que pueden crear recursos sin CMEK.

  3. Haz clic en  Editar.

  4. Selecciona Personalizar, selecciona Reemplazar y, luego, haz clic en Agregar regla.

  5. Selecciona Personalizado y luego haz clic en Rechazar.

  6. En el campo Valor personalizado, ingresa is:bigquery.googleapis.com.

  7. Haz clic en Listo y, luego, en Guardar.

gcloud

  gcloud resource-manager org-policies --project=PROJECT_ID \
    deny gcp.restrictNonCmekServices is:bigquery.googleapis.com

Para verificar que la política se aplique de forma correcta, puedes intentar crear una tabla en el proyecto. El proceso falla, a menos que especifiques una clave de Cloud KMS.

Esta política también se aplica a las tablas de resultados de consultas en el proyecto. Puedes especificar una clave predeterminada del proyecto para que los usuarios no tengan que especificar de forma manual una clave cada vez que ejecuten una consulta en el proyecto.

Restringe las claves de Cloud KMS de un proyecto de BigQuery

Puedes usar la restricción constraints/gcp.restrictCmekCryptoKeyProjects para restringir las claves de Cloud KMS que puedes usar a fin de proteger un recurso en un proyecto de BigQuery.

Puedes especificar una regla, por ejemplo, “Para todos los recursos de BigQuery en proyectos/my-company-data-project, las claves de Cloud KMS que se usan en este proyecto deben provenir de proyectos/my-company-central-keys O projects/team-specific-keys".

Consola

  1. Abre la página Políticas de la organización.

    Ir a Políticas de la organización

  2. En el campo Filtro, ingresa constraints/gcp.restrictCmekCryptoKeyProjects y, luego, haz clic en Restringir los proyectos que pueden proporcionar CryptoKeys de KMS para CMEK.

  3. Haz clic en  Editar.

  4. Selecciona Personalizar, selecciona Reemplazar y, luego, haz clic en Agregar regla.

  5. Selecciona Personalizado y luego haz clic en Permitir.

  6. En el campo Valor personalizado, ingresa under:projects/<var>KMS_PROJECT_ID</var>.

  7. Haz clic en Listo y, luego, en Guardar.

gcloud

  gcloud resource-manager org-policies --project=PROJECT_ID \
    allow gcp.restrictCmekCryptoKeyProjects under:projects/KMS_PROJECT_ID

Para verificar que la política se haya aplicado correctamente, puedes intentar crear una tabla con una clave de Cloud KMS de un proyecto diferente. El proceso fallará.

Limitaciones de las políticas de la organización

Existen limitaciones asociadas con la configuración de una política de la organización.

Retraso en la propagación

Después de configurar o actualizar una política de la organización, la política nueva puede tardar hasta 15 minutos en aplicarse. BigQuery almacena en caché las políticas para no afectar de forma negativa la latencia de creación de tablas y consultas.

Permisos necesarios para establecer una política de la organización

Es posible que sea difícil adquirir permisos para configurar o actualizar la política de la organización con fines de prueba. Se te debe otorgar el rol de administrador de políticas de la organización, que solo se puede otorgar a nivel de la organización (en lugar de a nivel de proyecto o carpeta).

Aunque el rol se debe otorgar a nivel de la organización, aún es posible especificar una política que solo se aplique a un proyecto o una carpeta específicos.

Efecto de la rotación de claves de Cloud KMS

BigQuery no rota la clave de encriptación de una tabla de forma automática cuando se rota una clave de Cloud KMS asociada a la tabla. Todos los datos en las tablas existentes siguen protegidos por la versión de clave con la que se crearon.

Las tablas recién creadas usan la versión de la clave primaria en el momento de su creación.

Para actualizar una tabla a fin de usar la versión de clave más reciente, cámbiala a una clave de Cloud KMS diferente y, luego, vuelve a la original.

Impacto en la facturación de Cloud KMS

Cuando creas o truncas una tabla protegida por CMEK, BigQuery genera una clave de encriptación de clave intermedia que se encripta con la clave de Cloud KMS especificada.

Para la facturación, esto significa que ni tus llamadas a Cloud KMS ni sus costos asociados se escalan con el tamaño de la tabla. En el caso de las tablas protegidas con CMEK, puedes esperar una llamada a Cloud KMS cryptoKeys.encrypt por cada creación o truncamiento de la tabla y una llamada a Cloud KMS cryptoKeys.decrypt para cada tabla involucrada en una consulta. Estos métodos pertenecen a la categoría de Operaciones de claves: criptográficas que se enumeran en Precios de Cloud KMS.

Tanto leer como escribir en una tabla existente protegida con CMEK invoca cryptoKeys.decrypt de Cloud KMS porque se debe desencriptar la clave intermedia.

Limitaciones

Acceso de BigQuery a la clave de Cloud KMS

Se considera que una clave de Cloud KMS está disponible y que BigQuery puede acceder a ella si se dan las siguientes condiciones:

  • La clave está habilitada.
  • La cuenta de servicio de BigQuery tiene permisos de encriptación y desencriptación en la clave.

En las secciones que se incluyen a continuación, se describe el impacto en las inserciones de transmisión y los datos inaccesibles a largo plazo cuando no se puede acceder a una clave.

Impacto en las inserciones de transmisión

La clave de Cloud KMS debe estar disponible y se debe tener acceso a ella durante al menos 24 horas consecutivas en el período de 48 horas posterior a una solicitud de inserción de transmisión. Si la clave no está disponible o no se puede acceder a ella, puede que los datos transmitidos se pierdan por no ser completamente persistentes. Para obtener más información sobre la inserción de transmisión, consulta Transmite datos a BigQuery.

Impacto en los datos inaccesibles a largo plazo

Como BigQuery proporciona almacenamiento administrado, los datos inaccesibles a largo plazo no son compatibles con su arquitectura. Si la clave de Cloud KMS de una tabla de BigQuery determinada no está disponible y no se puede acceder a ella durante 60 días consecutivos, BigQuery podría optar por borrar la tabla y sus datos asociados. Al menos 7 días antes de que se borren los datos, BigQuery envía un correo electrónico a la dirección de correo electrónico que está asociada a la cuenta de facturación.

Usa fuentes de datos externas

Si consultas datos almacenados en una fuente de datos externa, como Cloud Storage, que tiene datos encriptados con CMEK, Cloud Storage administra la encriptación de datos. Por ejemplo, las tablas de BigLake admiten datos encriptados con CMEK en Cloud Storage.

Las tablas BigQuery y de BigLake no admiten Claves de encriptación proporcionadas por el cliente (CSEK).

Cambia entre la encriptación protegida por CMEK y la encriptación predeterminada

No puedes cambiar una tabla entre las encriptaciones predeterminadas y la encriptación de CMEK. Para cambiar la encriptación, copia la tabla con el conjunto de información de encriptación de destino o usa una consulta de SELECT * a fin de seleccionar la tabla en sí con la disposición WRITE_TRUNCATE.

Usa decoradores de tablas

Si proteges una tabla con Cloud KMS y reemplazas sus datos con el valor WRITE_TRUNCATE para una operación load, cp o query, entonces Los decoradores de rango no funcionarán dentro del límite de cambio de encriptación. Puedes usar decoradores de tablas, incluidos los decoradores de rangos, para consultar los datos anteriores o posteriores al límite, o consultar la instantánea en un momento determinado.

Consultas de tablas comodín

Las tablas protegidas por CMEK no se pueden consultar con un sufijo comodín.

Compatibilidad con ediciones

La compatibilidad con CMEK para BigQuery solo está disponible para BigQuery Enterprise Plus y BigQuery On-Demand. Los clientes de BigQuery de reservas heredadas de tasa fija anteriores al 5 de julio de 2023 conservan toda la asistencia existente para CMEK en el nivel Enterprise.

Asistencia de BigQuery Studio

Los elementos de código de BigQuery Studio, incluidas las consultas guardadas y los notebooks, no admiten CMEK.

Preguntas frecuentes

¿Quién necesita permiso para la clave de Cloud KMS?

Con las claves de encriptación administradas por el cliente, no se necesita especificar permisos repetidas veces. Siempre que la cuenta de servicio de BigQuery tenga permiso para usar la clave de Cloud KMS a fin de encriptar y desencriptar, cualquier persona con permiso en la tabla de BigQuery puede acceder a los datos, incluso si no tienen acceso directo a la clave de Cloud KMS.

¿Qué cuenta de servicio se usa?

La cuenta de servicio de BigQuery asociada con el proyecto de Google Cloud de la tabla se usa para desencriptar los datos de la tabla. Las cuentas de servicio de BigQuery son únicas para cada proyecto. En el caso de un trabajo que escribe datos en una tabla anónima con protección de Cloud KMS, se usa la cuenta de servicio correspondiente al proyecto de ese trabajo.

Como ejemplo, considera tres tablas protegidas por CMEK: table1, table2 y table3. Para consultar datos desde {project1.table1, project2.table2} con la tabla de destino {project3.table3}:

  • Usa la cuenta de servicio de project1 para project1.table1.
  • Usa la cuenta de servicio de project2 para project2.table2.
  • Usa la cuenta de servicio de project3 para project3.table3.

¿Cómo puede usar BigQuery mi clave de Cloud KMS?

BigQuery usará la clave de Cloud KMS para desencriptar datos en respuesta a una consulta del usuario, como tabledata.list o jobs.insert.

BigQuery también puede usar la clave para realizar mantenimiento de datos y tareas de optimización de almacenamiento, como la conversión de datos a un formato optimizado para la lectura.

¿Qué bibliotecas de criptografía se usan?

BigQuery utiliza de Cloud KMS para la funcionalidad de CMEK. Cloud KMS usa Tink para la encriptación.

¿Cómo obtener más ayuda?

Si tienes preguntas que no se responden aquí, consulta Asistencia de BigQuery.

Solución de errores

A continuación, se describen errores comunes y mitigaciones recomendadas.

Error Recomendación
Otorga la función de Encriptador/Desencriptador clave de encriptación de Cloud KMS. La cuenta de servicio de BigQuery asociada a tu proyecto no tiene los permisos de IAM suficientes para operar en la clave de Cloud KMS especificada. Sigue las instrucciones en el error o en esta documentación para otorgar los permisos de IAM adecuados.
Las opciones de configuración de encriptación de la tabla existentes no coinciden con las opciones de configuración de encriptación que se especificaron en la solicitud. Esto puede suceder en situaciones en que la tabla de destino tiene una configuración de encriptación que no coincide con la configuración de encriptación en tu solicitud. Como mitigación, use la disposición de escritura TRUNCATE para reemplazar la tabla o especifica una tabla de destino diferente.
Esta región no es compatible. La región de la clave de Cloud KMS no coincide con la región del conjunto de datos de BigQuery de la tabla de destino. Como mitigación, selecciona una clave en una región que coincida con tu conjunto de datos o carga en un conjunto de datos que coincida con la región de la clave.
El administrador requiere que especifiques una clave de encriptación para las consultas en el proyecto PROJECT_ID.. Una política de la organización impidió crear un recurso o ejecutar una consulta. A fin de obtener más información sobre esta política, consulta Solicitud de CMEK para todos los recursos en un proyecto de BigQuery.
El administrador evita que se usen claves de KMS del proyecto KMS_PROJECT_ID para proteger los recursos del proyecto PROJECT_ID. Una política de la organización impidió crear un recurso o ejecutar una consulta. Para obtener más información sobre esta política, consulta Restringe las claves de Cloud KMS de un proyecto de BigQuery.