Questa pagina descrive come utilizzare le chiavi di crittografia gestite dal cliente create manualmente (CMEK) per Spanner.
Per scoprire di più sulle chiavi CMEK, consulta Chiavi di crittografia gestite dal cliente (CMEK).
Creare un database compatibile con CMEK
Crea una chiave in Cloud Key Management Service (Cloud KMS). Spanner supporta:
La chiave deve trovarsi nella stessa località dell'istanza Spanner. Ad esempio, se la configurazione dell'istanza Spanner è
us-west1
, anche la posizione del portachiavi deve essereus-west1
.Non tutti gli Spanner configurazione di istanze multiregionali ha una posizione del keyring corrispondente di Cloud KMS. Non potrai creare database abilitati per CMEK in quelle istanze Spanner.
Se hai già una chiave Cloud KMS nella posizione corretta, puoi saltare questo passaggio.
Per maggiori informazioni, consulta le seguenti risorse:
Concedi a Spanner l'accesso alla chiave.
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=my_spanner_project
Se ti viene chiesto di installare il componente Comandi gcloud beta, digita
Y
. Dopo l'installazione, il comando viene riavviato automaticamente.La Identità servizi gcloud crea o ottiene un agente di servizio che Spanner può usare per accedere alla chiave Cloud KMS sul tuo per conto tuo.
L'ID account di servizio ha il formato di un indirizzo email:
Service identity created: service-xxx@gcp-sa-spanner.iam.gserviceaccount.com
Concedi il ruolo
cloudkms.cryptoKeyEncrypterDecrypter
al servizio :gcloud kms keys add-iam-policy-binding my_kms_key \ --location my_kms_key_location \ --keyring my_kms_key_ring \ --project=my_kms_project \ --member serviceAccount:service-xxx@gcp-sa-spanner.iam.gserviceaccount.com \ --role roles/cloudkms.cryptoKeyEncrypterDecrypter
Visualizzerai:
Updated IAM policy for key [my-kms-key]
Questo ruolo garantisce che l'account di servizio abbia l'autorizzazione per criptare e con la chiave Cloud KMS. Per ulteriori informazioni, vedi Autorizzazioni e ruoli di Cloud KMS.
Crea il database e specifica la chiave Cloud KMS.
Console
1. Vai alla pagina Istanze di Spanner nella console Google Cloud.
2. Fai clic sul nome dell'istanza in cui creare il database.
3. Fai clic su Crea database e compila i campi obbligatori.
4. Fai clic su Mostra opzioni di crittografia.
5. Seleziona Usa una chiave di crittografia gestita dal cliente (CMEK).
6. Seleziona la chiave dall'elenco a discesa.
L'elenco delle chiavi è limitato al progetto Google Cloud corrente. Per utilizzare una chiave di un altro progetto Google Cloud, crea la classe utilizzando gcloud anziché la console Google Cloud.
Una volta creato il database, puoi verificare che sia supportato da CMEK visualizzando la pagina Dettagli database.
gcloud
gcloud spanner databases create example_db \ --project=my_spanner_project \ --instance=my_spanner_instance \ --ddl="CREATE TABLE Users (Id INT64 NOT NULL, FirstName STRING(100) NOT NULL, LastName STRING(100) NOT NULL,) PRIMARY KEY (Id)" \ --kms-project=my_kms_project \ --kms-location=my_kms_key_location \ --kms-keyring=my_kms_key_ring \ --kms-key=my_kms_key
Per verificare che un database sia abilitato per CMEK:
gcloud spanner databases describe example_db \ --project=my_spanner_project \ --instance=my_spanner_instance
I database abilitati per CMEK includono un campo per
encryptionConfig
, come mostrato in questo esempio:encryptionConfig: kmsKeyName: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
C#
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; } }
C++
Vai
Java
Node.js
PHP
Python
Ruby
# project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" # kms_key_name = "Database eencryption KMS key" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id instance = spanner.instance instance_id job = instance.create_database database_id, statements: [ "CREATE TABLE Singers ( SingerId INT64 NOT NULL, FirstName STRING(1024), LastName STRING(1024), SingerInfo BYTES(MAX) ) PRIMARY KEY (SingerId)", "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" ], encryption_config: { kms_key_name: kms_key_name } puts "Waiting for create database operation to complete" job.wait_until_done! database = job.database puts "Database #{database.database_id} created with encryption key #{database.encryption_config.kms_key_name}"
Visualizza le versioni della chiave in uso
Le informazioni sulle versioni della chiave provengono dal campo encryption_info
del database.
Quando la versione della chiave di un database cambia, la modifica non viene propagata immediatamente
a encryption_info
. Potrebbe essere necessario un po' di tempo prima che la modifica venga applicata nel campo delle informazioni.
Console
Le informazioni sulla crittografia vengono visualizzate nella pagina Dettagli del database.
gcloud
Per ottenere il valore encryption_info
di un database, chiama
databases describe
o
databases list
. Ad esempio:
gcloud spanner databases describe example_db \
--project=my_spanner_project \
--instance=my_spanner_instance
Ecco l'output:
name: projects/my-project/instances/test-instance/databases/example-db
encryptionConfig:
kmsKeyName: projects/google.com:cloud-spanner-demo/locations/us-central1/keyRings/cmek_demo/cryptoKeys/backup-key
encryptionInfo:
encryptionType: CUSTOMER_MANAGED_ENCRYPTION
Disattiva la chiave
Disattiva le versioni della chiave in uso seguendo queste istruzioni per ogni versione della chiave.
Attendi che la modifica venga applicata. La disattivazione di una chiave può richiedere fino a 3 ore per la propagazione.
Verifica che i dati non siano più accessibili:
gcloud spanner databases execute-sql example_db \ --project=my_spanner_project \ --instance=my_spanner_instance \ --sql='SELECT * FROM Users'
Verrà visualizzato il seguente errore:
KMS key required by the Spanner resource is not accessible.
Attiva la chiave
Abilita le versioni della chiave utilizzate dal database seguendo queste istruzioni per ogni chiave completamente gestita.
Attendi che la modifica venga applicata. L'abilitazione di una chiave può richiedere fino a 3 ore per la propagazione.
Verifica che i dati siano accessibili:
gcloud spanner databases execute-sql example_db \ --project=my_spanner_project \ --instance=my_spanner_instance \ --sql='SELECT * FROM Users'
Se la modifica è stata applicata, il comando verrà eseguito correttamente.
Esegui il backup di un database
Per impostazione predefinita, i backup creati da un database utilizzano la stessa configurazione di crittografia del database stesso. Facoltativamente, puoi specificare un valore configurazione della crittografia per un backup.
Per creare un backup:
Console
Vai alla pagina Dettagli database nella console Google Cloud.
Nella scheda Backup/Ripristino, fai clic su Crea.
Inserisci un nome per il backup e seleziona una data di scadenza.
Seleziona Utilizza una chiave di crittografia gestita dal cliente (CMEK) e scegli una chiave. dall'elenco a discesa.
Fai clic su Crea.
La tabella Backup mostra le informazioni sulla crittografia per ogni backup.
gcloud
gcloud spanner backups create my_backup \
--project=my_spanner_project \
--instance=my_spanner_instance \
--database=example_db \
--retention-period=1y \
--encryption-type=customer_managed_encryption \
--kms-project=my_kms_project \
--kms-location=my_kms_key_location \
--kms-keyring=my_kms_key_ring \
--kms-key=my_kms_key
--async
Per verificare che il backup creato sia criptato con CMEK:
gcloud spanner backups describe my_backup \
--project=my_spanner_project \
--instance=my_spanner_instance
C#
using Google.Cloud.Spanner.Admin.Database.V1;
using Google.Cloud.Spanner.Common.V1;
using Google.Protobuf.WellKnownTypes;
using System;
using System.Threading.Tasks;
public class CreateBackupWithEncryptionKeyAsyncSample
{
public async Task<Backup> CreateBackupWithEncryptionKeyAsync(string projectId, string instanceId, string databaseId, string backupId, CryptoKeyName kmsKeyName)
{
// Create a DatabaseAdminClient instance.
DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.Create();
// Create the CreateBackupRequest with encryption configuration.
CreateBackupRequest request = new CreateBackupRequest
{
ParentAsInstanceName = InstanceName.FromProjectInstance(projectId, instanceId),
BackupId = backupId,
Backup = new Backup
{
DatabaseAsDatabaseName = DatabaseName.FromProjectInstanceDatabase(projectId, instanceId, databaseId),
ExpireTime = DateTime.UtcNow.AddDays(14).ToTimestamp(),
},
EncryptionConfig = new CreateBackupEncryptionConfig
{
EncryptionType = CreateBackupEncryptionConfig.Types.EncryptionType.CustomerManagedEncryption,
KmsKeyNameAsCryptoKeyName = kmsKeyName,
},
};
// Execute the CreateBackup request.
var operation = await databaseAdminClient.CreateBackupAsync(request);
Console.WriteLine("Waiting for the operation to finish.");
// Poll until the returned long-running operation is complete.
var completedResponse = await operation.PollUntilCompletedAsync();
if (completedResponse.IsFaulted)
{
Console.WriteLine($"Error while creating backup: {completedResponse.Exception}");
throw completedResponse.Exception;
}
var backup = completedResponse.Result;
Console.WriteLine($"Backup {backup.Name} of size {backup.SizeBytes} bytes " +
$"was created at {backup.CreateTime} " +
$"using encryption key {kmsKeyName}");
return backup;
}
}
C++
Vai
Java
Node.js
PHP
Python
Ruby
# project_id = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"
# backup_id = "Your Spanner backup ID"
# kms_key_name = "Your backup encryption database KMS key"
require "google/cloud/spanner"
spanner = Google::Cloud::Spanner.new project: project_id
client = spanner.client instance_id, database_id
instance = spanner.instance instance_id
database = instance.database database_id
expire_time = Time.now + 14 * 24 * 3600 # 14 days from now
encryption_config = {
encryption_type: :CUSTOMER_MANAGED_ENCRYPTION,
kms_key_name: kms_key_name
}
job = database.create_backup backup_id, expire_time, version_time: version_time, encryption_config: encryption_config
puts "Backup operation in progress"
job.wait_until_done!
backup = instance.backup backup_id
puts "Backup #{backup.backup_id} of size #{backup.size_in_bytes} bytes was created at #{backup.create_time} using encryption key #{kms_key_name}"
Ripristina da un backup
Per impostazione predefinita, i database ripristinati da un backup utilizzano la stessa configurazione di crittografia del backup stesso, ma puoi sostituire questo comportamento specificando una configurazione di crittografia diversa per il database ripristinato. Se il backup è protetto da CMEK, la versione della chiave utilizzata per creare il backup deve essere disponibile per poter essere decriptata.
Per ripristinare un database:
Console
Vai alla pagina Dettagli istanza nella console Cloud.
Nella scheda Backup/Ripristino, seleziona un backup e fai clic su Ripristina.
Seleziona l'istanza da ripristinare e assegna un nome al database ripristinato.
Se vuoi utilizzare CMEK con il database ripristinato, seleziona Utilizza una chiave di crittografia gestita dal cliente (CMEK) e seleziona una chiave da dall'elenco a discesa.
gcloud
gcloud spanner databases restore --async \
--project=my_spanner_project \
--destination-instance=destination_instance \
--destination-database=example_db_restored \
--source-instance=my_spanner_instance \
--source-backup=my_backup
Verifica che il database ripristinato sia criptato con CMEK:
gcloud spanner databases describe example_db_restored \
--project=my_spanner_project \
--instance=destination_instance
Per ulteriori informazioni, consulta Ripristinare un database da un backup.
C#
using Google.Cloud.Spanner.Admin.Database.V1;
using Google.Cloud.Spanner.Common.V1;
using System;
using System.Threading.Tasks;
public class RestoreDatabaseWithEncryptionAsyncSample
{
public async Task<Database> RestoreDatabaseWithEncryptionAsync(string projectId, string instanceId, string databaseId, string backupId, CryptoKeyName kmsKeyName)
{
// Create a DatabaseAdminClient instance.
DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.Create();
// Create the RestoreDatabaseRequest with encryption configuration.
RestoreDatabaseRequest request = new RestoreDatabaseRequest
{
ParentAsInstanceName = InstanceName.FromProjectInstance(projectId, instanceId),
DatabaseId = databaseId,
BackupAsBackupName = BackupName.FromProjectInstanceBackup(projectId, instanceId, backupId),
EncryptionConfig = new RestoreDatabaseEncryptionConfig
{
EncryptionType = RestoreDatabaseEncryptionConfig.Types.EncryptionType.CustomerManagedEncryption,
KmsKeyNameAsCryptoKeyName = kmsKeyName,
}
};
// Execute the RestoreDatabase request.
var operation = await databaseAdminClient.RestoreDatabaseAsync(request);
Console.WriteLine("Waiting for the operation to finish.");
// Poll until the returned long-running operation is complete.
var completedResponse = await operation.PollUntilCompletedAsync();
if (completedResponse.IsFaulted)
{
Console.WriteLine($"Error while restoring database: {completedResponse.Exception}");
throw completedResponse.Exception;
}
var database = completedResponse.Result;
var restoreInfo = database.RestoreInfo;
Console.WriteLine($"Database {restoreInfo.BackupInfo.SourceDatabase} " +
$"restored to {database.Name} " +
$"from backup {restoreInfo.BackupInfo.Backup} " +
$"using encryption key {database.EncryptionConfig.KmsKeyName}");
return database;
}
}
C++
Vai
Java
Node.js
PHP
Python
Ruby
# project_id = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID of where to restore"
# backup_id = "Your Spanner backup ID"
# kms_key_name = "Your backup encryption database KMS key"
require "google/cloud/spanner"
spanner = Google::Cloud::Spanner.new project: project_id
instance = spanner.instance instance_id
backup = instance.backup backup_id
encryption_config = {
encryption_type: :CUSTOMER_MANAGED_ENCRYPTION,
kms_key_name: kms_key_name
}
job = backup.restore database_id, encryption_config: encryption_config
puts "Waiting for restore backup operation to complete"
job.wait_until_done!
database = job.database
restore_info = database.restore_info
puts "Database #{restore_info.backup_info.source_database_id} was restored to #{database.database_id} from backup #{restore_info.backup_info.backup_id} using encryption key #{database.encryption_config.kms_key_name}"
Visualizza gli audit log per la chiave Cloud KMS
Accertati che la registrazione è abilitata per l'API Cloud KMS nel tuo progetto.
Vai a Esplora log nella console Cloud.
Limita le voci di log alla chiave Cloud KMS aggiungendo quanto segue a Query Builder:
resource.type="cloudkms_cryptokey" resource.labels.location="my_kms_key_location" resource.labels.key_ring_id="my_kms_key_ring" resource.labels.crypto_key_id="my_kms_key"
In base alle normali operazioni, le azioni di crittografia e decriptazione vengono registrate con
INFO
gravità. Queste voci vengono registrate come zone in Spanner esegue il polling della chiave Cloud KMS ogni 5 minuti circa.Se Spanner non riesce ad accedere alla chiave, le operazioni vengono registrate come
ERROR
.