Clés Cloud KMS gérées par le client

Par défaut, BigQuery chiffre votre contenu stocké au repos. puis traite et gère ce chiffrement sans aucune action supplémentaire de votre part. Les données d'une table BigQuery sont tout d'abord chiffrées à l'aide de clés de chiffrement de données. Ces clés sont ensuite chiffrées par des clés de chiffrement de clés, dans le cadre du processus appelé chiffrement encapsulé. Les clés de chiffrement de clés ne chiffrent pas directement les données, mais chiffrent plutôt les clés de chiffrement des données qui sont utilisées par Google pour chiffrer vos données. Pour en savoir plus, consultez la section Cloud Key Management Service (KMS).

Si vous souhaitez contrôler vous-même le chiffrement, vous pouvez utiliser des clés gérées par le client (CMEK, Customer-Managed Encryption Keys) pour BigQuery. Au lieu de laisser Google gérer les clés de chiffrement de clés qui protègent vos données, c'est vous qui vous chargez de cette tâche dans Cloud KMS. Ce document décrit en détail cette technique.

Découvrez les options de chiffrement disponibles dans Google Cloud. Pour en savoir plus sur les clés de chiffrement gérées par le client, y compris leurs avantages et leurs limites, consultez la page Clés de chiffrement gérées par le client.

Avant de commencer

  • Tous les éléments de données résidant dans le stockage géré BigQuery sont compatibles avec les CMEK. Toutefois, si vous interrogez également des données stockées dans une source de données externe telle que Cloud Storage qui contient des données chiffrées par CMEK, le chiffrement des données est géré par Cloud Storage. Par exemple, les tables BigLake acceptent les données chiffrées avec CMEK dans Cloud Storage.

    BigQuery et les tables BigLake ne sont pas compatibles avec les clés de chiffrement fournies par le client (CSEK).

  • Déterminez si vous allez exécuter BigQuery et Cloud KMS dans le même projet Google Cloud ou dans des projets différents. Dans cette documentation, voici les conventions qui sont utilisées :

    • PROJECT_ID : ID du projet exécutant BigQuery
    • PROJECT_NUMBER : numéro du projet exécutant BigQuery
    • KMS_PROJECT_ID : ID du projet exécutant Cloud KMS (même s'il correspond également au projet exécutant BigQuery)
    Pour en savoir plus sur les ID et numéros de projet Google Cloud, consultez la section Identifier des projets.

  • BigQuery est automatiquement activé dans les nouveaux projets. Si vous exécutez BigQuery à partir d'un projet préexistant, activez l'API BigQuery.

  • Pour le projet Google Cloud qui exécute Cloud KMS, procédez comme suit :

    1. Activez l'API Cloud Key Management Service.
    2. Créez un trousseau de clés et une clé, comme décrit dans les sections concernant la création de trousseaux et de clés. Créez le trousseau de clés dans le même emplacement que celui de votre ensemble de données BigQuery :
      • Les ensembles de données multirégionaux doivent utiliser un trousseau de clés multirégional issu du même emplacement. Par exemple, un ensemble de données situé dans la région US doit être protégé par un trousseau de clés de la région us. De même, un ensemble de données se trouvant dans la région EU doit être protégé par un trousseau de clés de la région europe.
      • Les ensembles de données régionaux doivent utiliser des clés régionales correspondantes. Par exemple, un ensemble de données dans la région asia-northeast1 doit être protégé par un trousseau de clés de la région asia-northeast1.
      • Vous ne pouvez pas utiliser la région global lors de la configuration du chiffrement CMEK pour BigQuery dans la console Google Cloud. Toutefois, vous pouvez utiliser la région global lorsque vous configurez des clés CMEK pour BigQuery à l'aide de l'outil de ligne de commande bq ou de GoogleSQL.
      Pour en savoir plus sur les emplacements compatibles avec BigQuery et Cloud KMS, consultez la section Emplacements cloud.

Un appel de déchiffrement est effectué à l'aide de Cloud KMS une fois par requête vers une table chiffrée par CMEK. Pour en savoir plus, consultez la page Tarifs de Cloud KMS.

Spécification du chiffrement

Les clés Cloud KMS qui servent à protéger les données dans BigQuery sont des clés de type AES-256. Elles servent de clés de chiffrement de clés dans BigQuery, dans la mesure où elles chiffrent les clés de chiffrement de données qui chiffrent les données.

Accorder une autorisation de chiffrement et de déchiffrement

Pour protéger vos données BigQuery à l'aide d'une clé CMEK, accordez au compte de service BigQuery l'autorisation de chiffrer et de déchiffrer des données à l'aide de cette clé. Le rôle Chiffreur/Déchiffreur de CryptoKeys Cloud KMS accorde cette autorisation.

Assurez-vous que votre compte de service a bien été créé, puis utilisez Google Cloud Console pour déterminer l'ID du compte de service BigQuery. Ensuite, attribuez au compte de service le rôle approprié pour chiffrer et déchiffrer à l'aide de Cloud KMS.

Déclencher la création de votre compte de service

Votre compte de service BigQuery n'est pas créé initialement dès la création d'un projet. Pour déclencher la création de votre compte de service, saisissez une commande qui l'utilise (comme la commande bq show --encryption_service_account) ou appelez la méthode d'API projects.getServiceAccount. Exemple :

bq show --encryption_service_account --project_id=PROJECT_ID

Identifier l'ID du compte de service

L'ID du compte de service BigQuery se présente sous la forme suivante :

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

Les techniques suivantes montrent comment déterminer l'ID du compte de service BigQuery pour votre projet.

Console

  1. Accédez à la page Tableau de bord de la console Google Cloud.

    Accéder à la page "Tableau de bord"

  2. Cliquez sur la liste déroulante Sélectionner située en haut de la page. Sélectionnez votre projet dans la fenêtre Sélectionner qui s'affiche.

  3. L'ID et le numéro du projet sont tous deux affichés sur la carte Informations sur le projet du tableau de bord du projet :

    Fiche info concernant le projet

  4. Dans la chaîne suivante, remplacez PROJECT_NUMBER par votre numéro de projet. La nouvelle chaîne identifie l'ID de votre compte de service BigQuery.

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

bq

Exécutez la commande bq show avec l'option --encryption_service_account pour déterminer l'ID du compte de service :

bq show --encryption_service_account

La commande affiche l'ID du compte de service :

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

Attribuer le rôle de chiffreur/déchiffreur

Attribuez le rôle "Chiffreur/Déchiffreur de CryptoKeys Cloud KMS" au compte de service système BigQuery que vous avez copié dans votre presse-papiers. Ce compte se présente comme suit :

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

Console

  1. Ouvrez la page Clés cryptographiques dans la console Google Cloud.

    Ouvrir la page "Clés cryptographiques"

  2. Cliquez sur le nom du trousseau de clés contenant la clé.

  3. Cochez la case correspondant à la clé de chiffrement à laquelle vous souhaitez ajouter le rôle. L'onglet Autorisations s'ouvre.

  4. Cliquez sur Ajouter un membre.

  5. Saisissez l'adresse e-mail du compte de service (bq-PROJECT_NUMBER@bigquery-encryption.iam.gserviceaccount.com).

    • Si le compte de service figure déjà sur la liste des membres, il possède des rôles. Cliquez sur la liste déroulante du rôle actuellement affecté au compte de service bq-PROJECT_NUMBER@bigquery-encryption.iam.gserviceaccount.com.
  6. Cliquez sur la liste déroulante Sélectionnez un rôle, sélectionnez Cloud KMS, puis cliquez sur le rôle Chiffreur/Déchiffreur de CryptoKeys Cloud KMS.

  7. Cliquez sur Enregistrer pour appliquer le rôle au compte de service bq-PROJECT_NUMBER@bigquery-encryption.iam.gserviceaccount.com.

gcloud

Pour attribuer le rôle, vous pouvez utiliser Google Cloud CLI comme suit :

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

Remplacez les éléments suivants :

  • KMS_PROJECT_ID : ID de votre projet Google Cloud exécutant Cloud KMS
  • PROJECT_NUMBER : numéro de votre projet Google Cloud exécutant BigQuery (et non son ID)
  • KMS_KEY_LOCATION : nom de l'emplacement de votre clé Cloud KMS
  • KMS_KEY_RING : nom du trousseau de clés contenant votre clé Cloud KMS
  • KMS_KEY : nom de votre clé Cloud KMS

ID de ressource de la clé

Pour pouvoir utiliser des clés CMEK, vous devez disposer de l'ID de ressource de la clé Cloud KMS, comme décrit dans les exemples. Cette clé est sensible à la casse et se présente au format suivant :

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

Récupérer l'ID de ressource de la clé

  1. Ouvrez la page Clés cryptographiques dans la console Google Cloud.

    Ouvrir la page "Clés cryptographiques"

  2. Cliquez sur le nom du trousseau de clés contenant la clé.

  3. Pour la clé dont vous voulez récupérer l'ID de ressource, cliquez sur Plus .

  4. Cliquez sur Copier le nom de la ressource. L'ID de ressource pour la clé est copié dans votre presse-papiers. L'ID de ressource est également appelé nom de ressource.

Créer une table protégée par Cloud KMS

Pour créer une table protégée par Cloud KMS, procédez comme suit :

Console

  1. Ouvrez la page BigQuery dans la console Google Cloud.

    Accéder à BigQuery

  2. Dans le panneau Explorateur, développez votre projet et sélectionnez un ensemble de données.

  3. Développez l'option Actions puis cliquez sur Ouvrir.

  4. Dans le panneau de détails, cliquez sur Créer une table.

  5. Sur la page Créer une table, spécifiez les informations nécessaires pour créer une table vide avec une définition de schéma. Avant de cliquer sur Créer une table, définissez le type de chiffrement et spécifiez la clé Cloud KMS à utiliser avec la table :

    1. Cliquez sur Options avancées.
    2. Cliquez sur Clé gérée par le client.
    3. Sélectionnez la clé. Si la clé que vous souhaitez utiliser ne figure pas dans la liste, saisissez son ID de ressource.
  6. Cliquez sur Créer une table.

SQL

Utilisez l'instruction CREATE TABLE avec l'option kms_key_name :

  1. Dans la console Google Cloud, accédez à la page BigQuery.

    Accéder à BigQuery

  2. Dans l'éditeur de requête, saisissez l'instruction suivante :

    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. Cliquez sur Exécuter.

Pour en savoir plus sur l'exécution des requêtes, consultez Exécuter une requête interactive.

bq

Vous pouvez également créer la table à l'aide de l'outil de ligne de commande bq et de l'option --destination_kms_key. L'option --destination_kms_key spécifie l'ID de ressource de la clé à utiliser avec la table.

Pour créer une table vide à l'aide d'un schéma, exécutez la commande suivante :

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

Pour créer une table à partir d'une requête, exécutez la commande suivante :

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"

Pour en savoir plus sur l'outil de ligne de commande bq, consultez la page Utiliser l'outil de ligne de commande bq.

Terraform

Utilisez la ressource google_bigquery_table.

L'exemple suivant crée un ensemble de données nommé mytable et utilise également les ressources google_kms_crypto_key et google_kms_key_ring pour spécifier une clé Cloud Key Management Service pour l'ensemble de données.

Pour exécuter cet exemple, vous devez activer l'API Cloud Resource Manager et l'API 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"
}

Pour appliquer votre configuration Terraform dans un projet Google Cloud, suivez les procédures des sections suivantes.

Préparer Cloud Shell

  1. Lancez Cloud Shell.
  2. Définissez le projet Google Cloud par défaut dans lequel vous souhaitez appliquer vos configurations Terraform.

    Vous n'avez besoin d'exécuter cette commande qu'une seule fois par projet et vous pouvez l'exécuter dans n'importe quel répertoire.

    export GOOGLE_CLOUD_PROJECT=PROJECT_ID

    Les variables d'environnement sont remplacées si vous définissez des valeurs explicites dans le fichier de configuration Terraform.

Préparer le répertoire

Chaque fichier de configuration Terraform doit avoir son propre répertoire (également appelé module racine).

  1. Dans Cloud Shell, créez un répertoire et un nouveau fichier dans ce répertoire. Le nom du fichier doit comporter l'extension .tf, par exemple main.tf. Dans ce tutoriel, le fichier est appelé main.tf.
    mkdir DIRECTORY && cd DIRECTORY && touch main.tf
  2. Si vous suivez un tutoriel, vous pouvez copier l'exemple de code dans chaque section ou étape.

    Copiez l'exemple de code dans le fichier main.tf que vous venez de créer.

    Vous pouvez également copier le code depuis GitHub. Cela est recommandé lorsque l'extrait Terraform fait partie d'une solution de bout en bout.

  3. Examinez et modifiez les exemples de paramètres à appliquer à votre environnement.
  4. Enregistrez les modifications.
  5. Initialisez Terraform. Cette opération n'est à effectuer qu'une seule fois par répertoire.
    terraform init

    Vous pouvez également utiliser la dernière version du fournisseur Google en incluant l'option -upgrade :

    terraform init -upgrade

Appliquer les modifications

  1. Examinez la configuration et vérifiez que les ressources que Terraform va créer ou mettre à jour correspondent à vos attentes :
    terraform plan

    Corrigez les modifications de la configuration si nécessaire.

  2. Appliquez la configuration Terraform en exécutant la commande suivante et en saisissant yes lorsque vous y êtes invité :
    terraform apply

    Attendez que Terraform affiche le message "Apply completed!" (Application terminée).

  3. Ouvrez votre projet Google Cloud pour afficher les résultats. Dans la console Google Cloud, accédez à vos ressources dans l'interface utilisateur pour vous assurer que Terraform les a créées ou mises à jour.

Go

Avant d'essayer cet exemple, suivez les instructions de configuration pour Go du guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery pour Go.

Pour vous authentifier auprès de BigQuery, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez la page Configurer l'authentification pour les bibliothèques clientes.

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

Avant d'essayer cet exemple, suivez les instructions de configuration pour Java du guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery pour Java.

Pour vous authentifier auprès de BigQuery, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez la page Configurer l'authentification pour les bibliothèques clientes.

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

Avant d'essayer cet exemple, suivez les instructions de configuration pour Python du guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery pour Python.

Pour vous authentifier auprès de BigQuery, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez la page Configurer l'authentification pour les bibliothèques clientes.

Pour protéger une nouvelle table à l'aide d'une clé de chiffrement gérée par le client, définissez la propriété Table.encryption_configuration sur un objet EncryptionConfiguration avant de créer la table.
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}.")

Interroger une table protégée par une clé Cloud KMS

L'interrogation d'une table protégée par Cloud KMS ne requiert aucune démarche spécifique. BigQuery stocke le nom de la clé utilisée pour chiffrer le contenu de la table et utilise cette clé lorsqu'une table protégée par Cloud KMS est interrogée.

Tant que BigQuery a accès à la clé Cloud KMS qui sert à chiffrer le contenu de la table, vous pouvez utiliser les outils existants, la console BigQuery et l'interface de ligne de commande bq de la même manière qu'avec les tables chiffrées par défaut.

Protéger les résultats de requête à l'aide d'une clé Cloud KMS

Par défaut, les résultats de requête sont stockés dans une table temporaire chiffrée avec une clé gérée par Google. Pour utiliser une clé Cloud KMS afin de chiffrer les résultats de votre requête, sélectionnez l'une des options suivantes :

Console

  1. Ouvrez la page BigQuery dans la console Google Cloud.

    Accéder à BigQuery

  2. Cliquez sur Saisir une nouvelle requête.

  3. Saisissez une requête GoogleSQL valide dans la zone de texte de la requête.

  4. Cliquez sur Plus, puis sur Paramètres de requête et enfin sur Options avancées.

  5. Sélectionnez Chiffrement géré par le client.

  6. Sélectionnez la clé. Si la clé que vous souhaitez utiliser ne figure pas dans la liste, saisissez son ID de ressource.

  7. Cliquez sur Enregistrer.

  8. Cliquez sur Run (Exécuter).

bq

Spécifiez l'option --destination_kms_key pour protéger la table de destination ou les résultats de la requête (si vous utilisez une table temporaire) avec votre clé Cloud KMS. L'option --destination_kms_key spécifie l'ID de ressource de la clé à utiliser avec la table de destination ou la table résultante.

Vous pouvez également spécifier l'option --destination_table pour indiquer la destination des résultats de la requête. Si l'option --destination_table n'est pas spécifiée, les résultats de la requête sont écrits dans une table temporaire.

Pour interroger une table, exécutez la commande suivante :

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"

Pour en savoir plus sur l'outil de ligne de commande bq, consultez la page Utiliser l'outil de ligne de commande 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

Avant d'essayer cet exemple, suivez les instructions de configuration pour Java du guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery pour Java.

Pour vous authentifier auprès de BigQuery, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez la page Configurer l'authentification pour les bibliothèques clientes.

Pour protéger une nouvelle table à l'aide d'une clé de chiffrement gérée par le client, définissez la propriété Table.encryption_configuration sur un objet EncryptionConfiguration avant de créer la table.
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")

Charger une table protégée par Cloud KMS

Pour charger un fichier de données dans une table protégée par Cloud KMS, procédez comme suit :

Console

Pour protéger une table de destination de tâches de chargement à l'aide d'une clé de chiffrement gérée par le client, spécifiez la clé au moment de charger la table.

  1. Ouvrez la page BigQuery dans la console Google Cloud.

    Accéder à BigQuery

  2. Dans le panneau Explorateur, développez votre projet et sélectionnez un ensemble de données.

  3. Dans le panneau de détails, cliquez sur Create table (Créer une table).

  4. Saisissez les options que vous souhaitez utiliser pour le chargement de la table, mais avant de cliquer sur Créer une table, sélectionnez Options avancées.

  5. Sous Chiffrement, sélectionnez Clé gérée par le client.

  6. Cliquez sur la liste déroulante Sélectionner une clé gérée par le client et choisissez la clé à utiliser. Si vous ne voyez aucune clé, saisissez un ID de ressource de clé.

    Options avancées.

  7. Cliquez sur Créer une table.

bq

Pour protéger une table de destination de tâches de chargement à l'aide d'une clé de chiffrement gérée par le client, spécifiez l'option --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
Exemple :
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

Pour protéger une table de destination de tâches de chargement à l'aide d'une clé de chiffrement gérée par le client, définissez la propriété LoadJobConfig.destination_encryption_configuration sur un objet EncryptionConfiguration et chargez la table.

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")

Insérer des données en flux continu dans une table protégée par Cloud KMS

Vous pouvez insérer des données en flux continu dans votre table BigQuery protégée par une clé CMEK sans spécifier de paramètres supplémentaires. Notez que ces données sont chiffrées dans le tampon et à l'emplacement final grâce à votre clé Cloud KMS. Avant de diffuser des données dans une table protégée par une clé CMEK, vérifiez les exigences en matière de disponibilité et d'accessibilité des clés.

Pour en savoir plus sur la diffusion de données, consultez la page Insérer des données en flux continu dans BigQuery.

Remplacer le chiffrement par défaut d'une table par la protection Cloud KMS

bq

Vous pouvez exécuter la commande bq cp en spécifiant l'option --destination_kms_key pour copier une table protégée avec le chiffrement par défaut dans une nouvelle table ou dans la table d'origine, protégée par Cloud KMS. L'option --destination_kms_key spécifie l'ID de ressource de la clé à utiliser avec la table de destination.

Pour copier une table utilisant le chiffrement par défaut dans une nouvelle table protégée par Cloud KMS, exécutez la commande suivante :

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 vous souhaitez copier une table protégée par le chiffrement par défaut dans la même table, mais en utilisant la protection Cloud KMS, exécutez la commande suivante :

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 vous souhaitez remplacer la protection de Cloud KMS d'une table par le chiffrement par défaut, copiez le fichier à son propre emplacement en exécutant la commande bq cp sans spécifier l'option --destination_kms_key.

Pour en savoir plus sur l'outil de ligne de commande bq, consultez la page Utiliser l'outil de ligne de commande 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

Avant d'essayer cet exemple, suivez les instructions de configuration pour Python du guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery pour Python.

Pour vous authentifier auprès de BigQuery, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez la page Configurer l'authentification pour les bibliothèques clientes.

Pour protéger la destination d'une opération de copie de table à l'aide d'une clé de chiffrement gérée par le client, définissez la propriété QueryJobConfig.destination_encryption_configuration sur un objet EncryptionConfiguration et copiez la table.

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")

Vérifier si une table est protégée par Cloud KMS

  1. Dans la console Google Cloud, développez l'ensemble de données en cliquant sur la flèche bleue située à gauche de son nom ou en double-cliquant sur son nom. Les tables et les vues de l'ensemble de données s'affichent.

  2. Cliquez sur le nom de la table.

  3. Cliquez sur Détails. La page Détails de la table affiche la description et les informations de la table.

  4. Si la table est protégée par Cloud KMS, le champ Clé de chiffrement gérée par le client affiche l'ID de ressource de la clé.

    Table protégée.

Modifier la clé Cloud KMS d'une table BigQuery

Pour modifier la clé Cloud KMS d'une table existante protégée par une clé de chiffrement gérée par le client, vous pouvez exécuter une requête ALTER TABLE, utiliser l'API ou l'outil de ligne de commande bq. Il existe deux façons de modifier la clé Cloud KMS à l'aide de l'API et de l'outil de ligne de commande bq : update et cp.

La commande update sert à modifier la clé Cloud KMS d'une table protégée par CMEK.

La commande cp vous permet de modifier la clé Cloud KMS d'une table protégée par une clé CMEK, de remplacer le chiffrement par défaut par la protection CMEK, ou de remplacer la protection CMEK par le chiffrement par défaut.

La commande update présente l'avantage d'être plus rapide que cp et de permettre l'utilisation de décorateurs de table.

SQL

Utilisez l'instruction ALTER TABLE SET OPTIONS pour mettre à jour le champ kms_key_name d'une table :

  1. Dans la console Google Cloud, accédez à la page BigQuery.

    Accéder à BigQuery

  2. Dans l'éditeur de requête, saisissez l'instruction suivante :

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

  3. Cliquez sur Exécuter.

Pour en savoir plus sur l'exécution des requêtes, consultez Exécuter une requête interactive.

bq

Vous pouvez exécuter la commande bq cp en spécifiant l'option --destination_kms_key pour modifier la clé d'une table protégée par Cloud KMS. L'option --destination_kms_key spécifie l'ID de ressource de la clé à utiliser avec la table.

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

Pour modifier la clé de chiffrement gérée par le client d'une table, spécifiez un autre objet EncryptionConfiguration pour la propriété Table.encryption_configuration et mettez à jour la table.

# 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

Définir une clé par défaut pour l'ensemble de données

Vous pouvez définir une clé Cloud KMS par défaut au niveau de l'ensemble de données. Celle-ci s'applique à toutes les tables nouvellement créées au sein de l'ensemble de données, à moins que vous ne spécifiiez une autre clé Cloud KMS au moment de la création de la table. La clé par défaut ne s'applique pas aux tables existantes. La modification de la clé par défaut n'altère pas les tables existantes et s'applique uniquement aux tables créées après cette modification.

Vous pouvez définir, modifier ou supprimer la clé par défaut de l'ensemble de données de plusieurs manières :

  • En spécifiant la clé par défaut dans le champ EncryptionConfiguration.kmsKeyName lorsque vous appelez la méthode datasets.insert ou datasets.patch

  • En spécifiant la clé par défaut dans l'option --default_kms_key lorsque vous exécutez la commande 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
    

Définir une clé par défaut pour le projet

Vous pouvez définir une clé Cloud KMS par défaut au niveau du projet, qui s'applique à tous les résultats de requête et aux tables nouvellement créées dans le projet, sauf si vous spécifiez une clé Cloud KMS différente. La clé par défaut ne s'applique pas aux tables existantes. La modification de la clé par défaut n'altère pas les tables existantes et s'applique uniquement aux tables créées après cette modification.

SQL

Utilisez l'instruction ALTER PROJECT SET OPTIONS pour mettre à jour le champ default_kms_key_name d'un projet : Vous pouvez trouver le nom de ressource de la clé sur la page Cloud KMS.

  1. Dans la console Google Cloud, accédez à la page BigQuery.

    Accéder à BigQuery

  2. Dans l'éditeur de requête, saisissez l'instruction suivante :

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

  3. Cliquez sur Exécuter.

Pour en savoir plus sur l'exécution des requêtes, consultez Exécuter une requête interactive.

bq

Vous pouvez utiliser la commande bq pour exécuter une instruction ALTER PROJECT SET OPTIONS afin de mettre à jour le champ default_kms_key_name d'un projet :

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");'

Utiliser les CMEK pour protéger les modèles BigQuery ML

BigQuery ML est compatible avec les CMEK. En plus du chiffrement par défaut fourni par BigQuery, vous pouvez utiliser vos propres clés Cloud Key Management Service pour chiffrer les modèles de machine learning, y compris les modèles TensorFlow importés.

Créer un modèle chiffré à l'aide d'une clé Cloud KMS

Pour créer un modèle chiffré, utilisez l'instruction CREATE MODEL et spécifiez KMS_KEY_NAME dans les options d'entraînement:

    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 même syntaxe s'applique également aux modèles TensorFlow importés:

    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

Limites

Les clés de chiffrement gérées par le client sont soumises aux restrictions suivantes lors du chiffrement des modèles de machine learning :

Remplacer le chiffrement par défaut d'un modèle par la protection Cloud KMS

Vous pouvez exécuter la commande bq cp avec l'option --destination_kms_key pour copier un modèle protégé par le chiffrement par défaut dans un nouveau modèle protégé par Cloud KMS. Vous pouvez également utiliser la commande bq cp avec l'option -f pour écraser un modèle protégé par le chiffrement par défaut et le mettre à jour pour utiliser la protection Cloud KMS à la place. L'option --destination_kms_key spécifie l'ID de ressource de la clé à utiliser avec le modèle de destination.

Pour copier un modèle doté du chiffrement par défaut dans un nouveau modèle protégé par Cloud KMS, exécutez la commande suivante :

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

Pour écraser un modèle doté du chiffrement par défaut et le mettre à jour pour utiliser la protection Cloud KMS à la place, procédez comme suit :

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

Pour remplacer un modèle avec protection Cloud KMS par un modèle avec chiffrement par défaut, procédez comme suit :

bq cp -f \
DATASET_ID.MODEL_ID DATASET_ID.MODEL_ID

Pour en savoir plus sur l'outil de ligne de commande bq, consultez la page Utiliser l'outil de ligne de commande bq.

Vérifier si un modèle est protégé par Cloud KMS

Exécutez la commande bq show pour vérifier si un modèle est protégé par une clé Cloud KMS. La clé de chiffrement se trouve dans le champ kmsKeyName.

bq show -m my_dataset.my_model

Vous pouvez également utiliser la console Google Cloud pour déterminer la clé Cloud KMS d'un modèle chiffré. Les informations CMEK se trouvent dans le champ Clé gérée par le client de la section Informations sur le modèle du volet Détails du modèle.

Modifier la clé Cloud KMS d'un modèle chiffré

Utilisez la commande bq update avec l'option --destination_kms_keypour modifier la clé d'un modèle protégé par Cloud KMS.

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

Utiliser les clés de projet ou d'ensemble de données par défaut

Si vous avez défini une clé Cloud KMS par défaut au niveau du projet ou de l'ensemble de données, BigQuery ML utilise automatiquement cette clé lors de la création de modèles. Utilisez l'instruction CREATE MODEL pour spécifier une autre clé afin de chiffrer le modèle si vous ne souhaitez pas utiliser la clé par défaut.

Utiliser les fonctions BigQuery ML avec des modèles chiffrés

Vous pouvez utiliser toutes les fonctions BigQuery ML avec un modèle chiffré sans spécifier de clé de chiffrement.

Utiliser CMEK pour protéger l'API BigQuery Connection

Pour les connexions Cloud SQL, vous pouvez protéger les identifiants de l'API BigQuery Connection à l'aide des CMEK.

Pour en savoir plus sur la création d'une connexion protégée par une clé CMEK, consultez la page Créer des connexions Cloud SQL.

Supprimer l'accès de BigQuery à la clé Cloud KMS

Vous pouvez supprimer l'accès de BigQuery à la clé Cloud KMS à tout moment en révoquant l'autorisation Identity and Access Management (IAM) pour cette clé.

La révocation de l'accès de BigQuery à une clé Cloud KMS peut affecter considérablement l'expérience utilisateur et entraîner des pertes de données :

  • Les données des tables protégées par des clés de chiffrement gérées par le client (CMEK) ne sont plus accessibles : les commandes query, cp, extract et tabledata.list échoueront toutes.

  • Aucune nouvelle donnée ne peut être ajoutée aux tables protégées par des clés CMEK.

  • Une fois l'accès rétabli, les performances des requêtes sur ces tables peuvent être réduites pendant plusieurs jours.

Contrôler l'utilisation des CMEK avec une règle d'administration

BigQuery s'intègre aux contraintes de règle d'administration CMEK pour vous permettre de spécifier des exigences de conformité en matière de chiffrement pour les ressources BigQuery de votre organisation.

Cette intégration vous permet d'effectuer les opérations suivantes :

  • Exiger des CMEK pour toutes les ressources BigQuery d'un projet.

  • Limitez les clés Cloud KMS pouvant être utilisées pour protéger les ressources d'un projet.

Exiger des CMEK pour toutes les ressources

Une règle courante consiste à exiger que les clés CMEK soient utilisées pour protéger toutes les ressources d'un ensemble spécifique de projets. Vous pouvez utiliser la contrainte constraints/gcp.restrictNonCmekServices pour appliquer cette règle dans BigQuery.

Si cette règle d'administration est définie, toutes les requêtes de création de ressources sans clé Cloud KMS spécifiée échouent.

Une fois cette règle définie, elle ne s'applique qu'aux nouvelles ressources du projet. Toutes les ressources existantes sans clé Cloud KMS continuent d'exister et sont accessibles sans problème.

Console

  1. Ouvrez la page Règles d'administration.

    Accéder à la page Règles d'administration

  2. Dans le champ Filtre, saisissez constraints/gcp.restrictNonCmekServices, puis cliquez sur Restreindre les services autorisés à créer des ressources sans CMEK.

  3. Cliquez sur Modifier.

  4. Sélectionnez Personnaliser, Remplacer, puis cliquez sur Ajouter une règle.

  5. Sélectionnez Personnalisé, puis cliquez sur Refuser.

  6. Dans le champ Valeur personnalisée, saisissez is:bigquery.googleapis.com.

  7. Cliquez sur OK, puis sur Enregistrer.

gcloud

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

Pour vérifier que la stratégie est appliquée, vous pouvez essayer de créer une table dans le projet. Le processus échoue, sauf si vous spécifiez une clé Cloud KMS.

Cette règle s'applique également aux tables de résultats de requête du projet. Vous pouvez spécifier une clé par défaut du projet afin que les utilisateurs n'aient pas à spécifier manuellement une clé chaque fois qu'ils exécutent une requête dans le projet.

Restreindre les clés Cloud KMS pour un projet BigQuery

La contrainte constraints/gcp.restrictCmekCryptoKeyProjects vous permet de restreindre les clés Cloud KMS que vous pouvez utiliser pour protéger une ressource dans un projet BigQuery.

Vous pouvez spécifier une règle. Par exemple, "pour toutes les ressources BigQuery dans projects/my-company-data-project, les clés Cloud KMS utilisées dans ce projet doivent provenir de projects/my-company-central-keys OU projects/team-specific-keys."

Console

  1. Ouvrez la page Règles d'administration.

    Accéder à la page Règles d'administration

  2. Dans le champ Filtre, saisissez constraints/gcp.restrictCmekCryptoKeyProjects, puis cliquez sur Limiter les projets pouvant fournir des clés CryptoKeys KMS pour CMEK.

  3. Cliquez sur Modifier.

  4. Sélectionnez Personnaliser, Remplacer, puis cliquez sur Ajouter une règle.

  5. Sélectionnez Personnalisé, puis cliquez sur Autoriser.

  6. Dans le champ Valeur personnalisée, saisissez under:projects/<var>KMS_PROJECT_ID</var>.

  7. Cliquez sur OK, puis sur Enregistrer.

gcloud

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

Pour vérifier que la règle a bien été appliquée, vous pouvez essayer de créer une table à l'aide d'une clé Cloud KMS d'un autre projet. Le processus échoue.

Limites des règles d'administration

La définition d'une règle d'administration comporte certaines limites.

Délai de propagation

Après avoir défini ou mis à jour une règle d'administration, la prise en compte de la nouvelle règle peut prendre jusqu'à 15 minutes. BigQuery met en cache les règles afin de ne pas affecter négativement la latence de création des requêtes et des tables.

Autorisations requises pour définir une règle d'administration

L'autorisation de définir ou de mettre à jour la règle d'administration peut s'avérer difficile à obtenir à des fins de test. Vous devez disposer du rôle Administrateur des règles d'administration, qui ne peut être accordé qu'au niveau de l'organisation (et non au niveau du projet ou du dossier).

Bien que le rôle doit être accordé au niveau de l'organisation, il est toujours possible de spécifier une stratégie qui ne s'applique qu'à un projet ou un dossier spécifique.

Impact de la rotation des clés Cloud KMS

BigQuery n'aligne pas automatiquement la rotation d'une clé de chiffrement de table avec la rotation de la clé Cloud KMS associée à cette table. Toutes les données des tables existantes continuent d'être protégées par la version de clé avec laquelle elles ont été créées.

Toutes les tables nouvellement créées utilisent la version de clé primaire au moment de leur création.

Pour mettre à jour une table de sorte qu'elle utilise la version de clé la plus récente, remplacez la table par une autre clé Cloud KMS, puis revenez à la version d'origine.

Impact sur la facturation Cloud KMS

Lorsque vous créez ou tronquez une table protégée par une clé CMEK, BigQuery génère une clé de chiffrement de clé intermédiaire, qui est ensuite chiffrée avec la clé Cloud KMS spécifiée.

Pour des raisons de facturation, cela signifie que ni vos appels à Cloud KMS ni les coûts associés ne s'adaptent à la taille de la table. Pour les tables protégées par une clé CMEK, vous pouvez vous attendre à un appel à Cloud KMS cryptoKeys.encrypt pour chaque création ou troncation de table, et à un appel à Cloud KMS cryptoKeys.decrypt pour chaque table impliquée dans une requête. Ces méthodes appartiennent à la catégorie Opérations de clé : chiffrement répertoriée dans la section Tarifs de Cloud KMS.

L'écriture ou la lecture dans le cadre d'une table protégée par une clé CMEK existante a pour effet d'appeler Cloud KMS cryptoKeys.decrypt, car la clé intermédiaire doit être déchiffrée.

Limites

Accès de BigQuery à la clé Cloud KMS

Une clé Cloud KMS est considérée comme disponible et accessible par BigQuery si elle répond aux exigences suivantes :

  • La clé est activée.
  • Le compte de service BigQuery détient des autorisations de chiffrement et de déchiffrement sur la clé.

Les sections suivantes décrivent l'impact qu'une clé inaccessible peut avoir sur les insertions en flux continu et sur les données inaccessibles à long terme.

Impact sur les insertions en flux continu

La clé Cloud KMS doit être disponible et accessible pendant au moins 24 heures consécutives au cours des 48 heures qui suivent une requête d'insertion en flux continu. Dans le cas contraire, il est possible que les données diffusées ne soient pas entièrement conservées, ce qui risque d'entraîner leur perte. Pour en savoir plus sur les insertions en flux continu, consultez la page Insérer des données en flux continu dans BigQuery.

Impact sur les données inaccessibles à long terme

Comme BigQuery assure un stockage géré, les données inaccessibles à long terme ne sont pas compatibles avec l'architecture de BigQuery. Si la clé Cloud KMS d'une table BigQuery donnée n'est pas disponible et accessible pendant 60 jours consécutifs, BigQuery peut choisir de supprimer cette table et les données associées. Au moins sept jours avant la suppression des données, BigQuery envoie un e-mail à l'adresse associée au compte de facturation.

Utiliser des sources de données externes

Si vous interrogez des données stockées dans une source de données externe telle que Cloud Storage qui contient des données chiffrées par CMEK, le chiffrement des données est géré par Cloud Storage. Par exemple, les tables BigLake acceptent les données chiffrées avec CMEK dans Cloud Storage.

BigQuery et les tables BigLake ne sont pas compatibles avec les clés de chiffrement fournies par le client (CSEK).

Basculer entre le chiffrement protégé par CMEK et le chiffrement par défaut

Vous ne pouvez pas basculer une table en place entre les chiffrements par défaut et le chiffrement CMEK. Pour basculer d'un chiffrement à l'autre, copiez la table avec les informations de chiffrement de destination définies ou utilisez une requête SELECT * pour sélectionner la table en elle-même avec une disposition WRITE_TRUNCATE.

Utiliser des décorateurs de table

Si vous protégez une table avec Cloud KMS, puis que vous remplacez les données de la table en utilisant la valeur WRITE_TRUNCATE pour une opération load, cp ou query, les décorateurs de plage ne fonctionnent pas à travers la limite de modification du chiffrement. Vous pouvez toujours utiliser des décorateurs de table, y compris des décorateurs de plage, pour interroger les données avant ou après la limite, ou interroger l'instantané à un moment donné.

Requêtes de tables génériques

Les tables protégées par des clés CMEK ne peuvent pas être interrogées à l'aide d'un suffixe générique.

Compatibilité des éditions

La compatibilité CMEK pour BigQuery n'est disponible que pour BigQuery Enterprise Plus et BigQuery On-Demand. Les clients BigQuery qui utilisent d'anciennes réservations à tarif forfaitaire souscrites avant le 5 juillet 2023 conservent la compatibilité CMEK au niveau Enterprise.

Compatibilité avec BigQuery Studio

Les éléments de code BigQuery Studio, y compris les requêtes enregistrées et les notebooks, ne sont pas compatibles avec CMEK.

Questions fréquentes

Qui doit détenir des autorisations sur la clé Cloud KMS ?

Si vous utilisez des clés de chiffrement gérées par le client, vous n'avez pas besoin de spécifier des autorisations à plusieurs reprises. Tant que le compte de service BigQuery est autorisé à utiliser la clé Cloud KMS pour effectuer des opérations de chiffrement et de déchiffrement, tous les membres ayant accès à la table BigQuery peuvent consulter les données (même s'ils ne disposent pas d'un accès direct à la clé Cloud KMS).

Quel compte de service est utilisé ?

Le compte de service BigQuery associé au projet Google Cloud de la table est utilisé pour déchiffrer les données qu'elle contient. Les comptes de service BigQuery sont uniques pour chaque projet. En outre, lorsque des données sont rédigées dans une table anonyme protégée par Cloud KMS, c'est le compte de service associé au projet où s'effectue la tâche qui est utilisé.

Prenons l'exemple de trois tables (table1, table2, table3) protégées par des clés de chiffrement gérées par le client. Pour interroger les données de {project1.table1, project2.table2} en utilisant la table de destination {project3.table3}, procédez comme suit :

  • Utiliser le compte de service project1 pour project1.table1
  • Utiliser le compte de service project2 pour project2.table2
  • Utiliser le compte de service project3 pour project3.table3

Comment BigQuery utilise-t-il ma clé Cloud KMS ?

BigQuery utilise la clé Cloud KMS pour déchiffrer des données en réponse à une requête utilisateur, par exemple tabledata.list ou jobs.insert.

La clé permet également à BigQuery d'effectuer des tâches de maintenance des données et d'optimisation du stockage, telles que la conversion de données dans un format optimisé en lecture.

Quelles sont les bibliothèques de cryptographie utilisées ?

BigQuery s'appuie sur Cloud KMS pour gérer les fonctionnalités CMEK. Cloud KMS utilise Tink pour effectuer le chiffrement.

Comment obtenir de l'aide ?

Si vous ne trouvez pas de réponse à vos questions dans cette documentation, consultez la page Assistance BigQuery.

Résoudre les erreurs

La section suivante décrit les erreurs courantes et présente les solutions recommandées.

Erreur Recommandation
Veuillez attribuer le rôle de chiffreur/déchiffreur de clés cryptographiques Cloud KMS Le compte de service BigQuery associé à votre projet ne dispose pas des autorisations IAM nécessaires pour utiliser la clé Cloud KMS spécifiée. Suivez les instructions fournies par l'erreur ou figurant dans cette documentation pour attribuer l'autorisation IAM appropriée.
Les paramètres de chiffrement de table existants ne correspondent pas aux paramètres spécifiés dans la requête Ce problème peut survenir lorsque la table de destination possède des paramètres de chiffrement différents de ceux de votre requête. Pour le résoudre, remplacez la table à l'aide de la disposition d'écriture TRUNCATE ou spécifiez une table de destination différente.
Vous ne pouvez pas sélectionner cette région La région de la clé Cloud KMS ne correspond pas à la région de l'ensemble de données BigQuery contenant la table de destination. Pour corriger cette erreur, sélectionnez une clé dans la région de votre ensemble de données ou chargez les données dans un ensemble de données appartenant à la même région que la clé.
Votre administrateur exige que vous spécifiiez une clé de chiffrement pour les requêtes dans le projet PROJECT_ID.. Une règle d'administration a empêché la création d'une ressource ou l'exécution d'une requête. Pour en savoir plus sur cette règle, consultez la section Exiger des CMEK pour toutes les ressources d'un projet BigQuery.
Votre administrateur empêche l'utilisation de clés KMS du projet KMS_PROJECT_ID pour protéger les ressources du projet PROJECT_ID. Une règle d'administration a empêché la création d'une ressource ou l'exécution d'une requête. Pour en savoir plus sur cette règle, consultez la page Restreindre les clés Cloud KMS d'un projet BigQuery.