Proteggere un database con chiavi di crittografia gestite dal cliente (CMEK)

Questa pagina descrive come utilizzare le chiavi di crittografia gestite dal cliente (CMEK) create manualmente per Spanner.

Per scoprire di più su CMEK, consulta la panoramica delle chiavi di crittografia gestite dal cliente (CMEK).

Crea un database abilitato per CMEK

  1. Crea una chiave in Cloud Key Management Service (Cloud KMS). Puoi utilizzare i seguenti tipi di chiavi che hanno diversi livelli di protezione in Spanner:

    La chiave deve trovarsi nella stessa località dell'istanza Spanner. Ad esempio, se la configurazione dell'istanza Spanner si trova in us-west1, anche la posizione del portachiavi Cloud KMS deve essere us-west1.

    Non tutte le configurazioni di istanze multiregionali di Spanner hanno una posizione del portachiavi Cloud KMS corrispondente. Per i database Spanner nelle configurazioni di istanze personalizzate, a due regioni o multiregionali, puoi utilizzare più chiavi Cloud KMS regionali (a regione singola) per proteggere il tuo database. Ad esempio:

    • Se il tuo database Spanner si trova nella configurazione dell'istanza multiregionale nam14, puoi creare chiavi Cloud KMS in us-east4, northamerica-northeast1 e us-east1.
    • Se il tuo database si trova in una configurazione di istanza personalizzata che utilizza nam3 come configurazione di base con una replica di sola lettura aggiuntiva in us-central2, puoi creare chiavi Cloud KMS in us-east4, us-east1, us-central1 e us-central2.

    (Facoltativo) Per visualizzare un elenco delle posizioni delle repliche nella configurazione dell'istanza Spanner, utilizza il comando gcloud spanner instances get-locations:

    gcloud spanner instances get-locations <var>INSTANCE_ID</var>
    

    Per maggiori informazioni, consulta le seguenti risorse:

  2. Concedi a Spanner l'accesso alla chiave.

    1. In Cloud Shell, crea e visualizza l'agente di servizio oppure visualizzalo se l'account esiste già:

      gcloud beta services identity create --service=spanner.googleapis.com \
          --project=PROJECT_ID

      Se ti viene chiesto di installare il componente gcloud Beta Commands, digita Y. Dopo l'installazione, il comando viene riavviato automaticamente.

      Il comando gcloud services identity crea o recupera l'agente di servizio che Spanner può utilizzare per accedere alla chiave Cloud KMS per tuo conto.

      L'ID account di servizio ha il formato di un indirizzo email:

      Service identity created: service-xxx@gcp-sa-spanner.iam.gserviceaccount.com
      
    2. Concedi il ruolo Autore crittografia/decrittografia CryptoKey Cloud KMS(cloudkms.cryptoKeyEncrypterDecrypter) al account di servizio per ogni regione (--location) nella configurazione dell'istanza Spanner. Per farlo, esegui il comando gcloud kms keys add-iam-policybinding:

      gcloud kms keys add-iam-policy-binding KMS_KEY \
          --location KMS_KEY_LOCATION \
          --keyring KMS_KEY_RING \
          --project=PROJECT_ID \
          --member serviceAccount:service-xxx@gcp-sa-spanner.iam.gserviceaccount.com \
          --role roles/cloudkms.cryptoKeyEncrypterDecrypter

      Ecco un output di esempio:

      Updated IAM policy for key [KMS_KEY]
      

      Se utilizzi più chiavi Cloud KMS per proteggere il tuo database, esegui il comando gcloud kms keys add-iam-policybinding per tutte le tue chiavi.

      Questo ruolo garantisce che il account di servizio disponga dell'autorizzazione per criptare e decriptare con la chiave Cloud KMS. Per saperne di più, consulta Ruoli e autorizzazioni di Cloud KMS.

  3. Crea il database e specifica la chiave Cloud KMS.

Console

Utilizza la console per creare database nelle configurazioni delle istanze regionali.

  1. Nella console Google Cloud , vai alla pagina Istanze.

    Vai a Istanze Spanner

  2. Fai clic sull'istanza in cui vuoi creare un database.

  3. Fai clic su Crea database e compila i campi obbligatori.

  4. Fai clic su Mostra opzioni di crittografia.

  5. Seleziona Chiave Cloud KMS.

  6. Seleziona una chiave dall'elenco a discesa.

    L'elenco delle chiavi è limitato al progetto Google Cloud corrente. Per utilizzare una chiave di un progetto Google Cloud diverso, crea il database utilizzando gcloud CLI anziché la consoleGoogle Cloud .

    Una volta creato il database, puoi verificare che sia abilitato a CMEK visualizzando la pagina Panoramica del database.

    Screenshot che mostra il tipo di crittografia e la chiave di un database

gcloud

Per creare un database abilitato per CMEK in una configurazione di istanza regionale, personalizzata o multiregionale, esegui il comando gcloud spanner databases create:

gcloud spanner databases create DATABASE \
  --project=SPANNER_PROJECT_ID \
  --instance=INSTANCE_ID \
  --ddl="CREATE TABLE Users (Id INT64 NOT NULL, FirstName STRING(100) NOT NULL, LastName STRING(100) NOT NULL,) PRIMARY KEY (Id)" \
  --kms-project=KMS_PROJECT_ID \
  --kms-location=KMS_KEY_LOCATION \
  --kms-keyring=KMS_KEYRING \
  --kms-keys=KMS_KEY_1[, KMS_KEY_2 ... ]

Per verificare che un database sia abilitato per CMEK, esegui il comando gcloud spanner databases describe:

gcloud spanner databases describe DATABASE \
  --project=SPANNER_PROJECT_ID \
  --instance=INSTANCE_ID

I database abilitati per CMEK includono un campo per encryptionConfig, come mostrato nell'output di esempio seguente:

encryptionConfig:
  kmsKeyNames:projects/my-kms-project/locations/eur5/keyRings/my-kms-key-ring/cryptoKeys/my-kms-key
  name: projects/my-spanner-project/instances/my-instance/databases/my-db
state: READY

Librerie client

C#

Per creare un database abilitato per CMEK in una configurazione dell'istanza regionale:


using Google.Cloud.Spanner.Admin.Database.V1;
using Google.Cloud.Spanner.Common.V1;
using System;
using System.Threading.Tasks;

public class CreateDatabaseWithEncryptionKeyAsyncSample
{
    public async Task<Database> CreateDatabaseWithEncryptionKeyAsync(string projectId, string instanceId, string databaseId, CryptoKeyName kmsKeyName)
    {
        // Create a DatabaseAdminClient instance that can be used to execute a
        // CreateDatabaseRequest with custom encryption configuration options.
        DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.Create();
        // Define create table statement for table #1.
        var createSingersTable =
            @"CREATE TABLE Singers (
                SingerId INT64 NOT NULL,
                FirstName STRING(1024),
                LastName STRING(1024),
                ComposerInfo BYTES(MAX)
            ) PRIMARY KEY (SingerId)";
        // Define create table statement for table #2.
        var createAlbumsTable =
            @"CREATE TABLE Albums (
                SingerId INT64 NOT NULL,
                AlbumId INT64 NOT NULL,
                AlbumTitle STRING(MAX)
            ) PRIMARY KEY (SingerId, AlbumId),
            INTERLEAVE IN PARENT Singers ON DELETE CASCADE";

        // Create the CreateDatabase request with encryption configuration and execute it.
        var request = new CreateDatabaseRequest
        {
            ParentAsInstanceName = InstanceName.FromProjectInstance(projectId, instanceId),
            CreateStatement = $"CREATE DATABASE `{databaseId}`",
            ExtraStatements = { createSingersTable, createAlbumsTable },
            EncryptionConfig = new EncryptionConfig
            {
                KmsKeyNameAsCryptoKeyName = kmsKeyName,
            },
        };
        var operation = await databaseAdminClient.CreateDatabaseAsync(request);

        // Wait until the operation has finished.
        Console.WriteLine("Waiting for the operation to finish.");
        var completedResponse = await operation.PollUntilCompletedAsync();
        if (completedResponse.IsFaulted)
        {
            Console.WriteLine($"Error while creating database: {completedResponse.Exception}");
            throw completedResponse.Exception;
        }

        var database = completedResponse.Result;
        Console.WriteLine($"Database {database.Name} created with encryption key {database.EncryptionConfig.KmsKeyName}");

        return database;
    }
}

Per creare un database abilitato per CMEK in una configurazione dell'istanza multiregionale:


using Google.Cloud.Spanner.Admin.Database.V1;
using Google.Cloud.Spanner.Common.V1;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

public class CreateDatabaseWithMultiRegionEncryptionAsyncSample
{
    public async Task<Database> CreateDatabaseWithMultiRegionEncryptionAsync(string projectId, string instanceId, string databaseId, IEnumerable<CryptoKeyName> kmsKeyNames)
    {
        // Create a DatabaseAdminClient instance that can be used to execute a
        // CreateDatabaseRequest with custom encryption configuration options.
        DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.Create();
        // Define create table statement for table #1.
        var createSingersTable =
            @"CREATE TABLE Singers (
                SingerId INT64 NOT NULL,
                FirstName STRING(1024),
                LastName STRING(1024),
                ComposerInfo BYTES(MAX)
            ) PRIMARY KEY (SingerId)";
        // Define create table statement for table #2.
        var createAlbumsTable =
            @"CREATE TABLE Albums (
                SingerId INT64 NOT NULL,
                AlbumId INT64 NOT NULL,
                AlbumTitle STRING(MAX)
             ) PRIMARY KEY (SingerId, AlbumId),
             INTERLEAVE IN PARENT Singers ON DELETE CASCADE";

        // Create the CreateDatabase request with encryption configuration and execute it.
        var request = new CreateDatabaseRequest
        {
            ParentAsInstanceName = InstanceName.FromProjectInstance(projectId, instanceId),
            CreateStatement = $"CREATE DATABASE `{databaseId}`",
            ExtraStatements = { createSingersTable, createAlbumsTable },
            EncryptionConfig = new EncryptionConfig
            {
                KmsKeyNamesAsCryptoKeyNames = { kmsKeyNames },
            },
        };
        var operation = await databaseAdminClient.CreateDatabaseAsync(request);

        // Wait until the operation has finished.
        Console.WriteLine("Waiting for the operation to finish.");
        var completedResponse = await operation.PollUntilCompletedAsync();
        if (completedResponse.IsFaulted)
        {
            Console.WriteLine($"Error while creating database: {completedResponse.Exception}");
            throw completedResponse.Exception;
        }

        var database = completedResponse.Result;
        Console.WriteLine($"Database {database.Name} created with encryption keys {string.Join(", ", kmsKeyNames)}");

        return database;
    }
}

C++

Per creare un database abilitato per CMEK in una configurazione dell'istanza regionale:

void CreateDatabaseWithEncryptionKey(
    google::cloud::spanner_admin::DatabaseAdminClient client,
    std::string const& project_id, std::string const& instance_id,
    std::string const& database_id,
    google::cloud::KmsKeyName const& encryption_key) {
  google::cloud::spanner::Database database(project_id, instance_id,
                                            database_id);
  google::spanner::admin::database::v1::CreateDatabaseRequest request;
  request.set_parent(database.instance().FullName());
  request.set_create_statement("CREATE DATABASE `" + database.database_id() +
                               "`");
  request.add_extra_statements