> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Spanner Database Backup Should Be Encrypted With Customer Managed Keys

### More Info:

Ensure Spanner Database Backups are encrypted with Customer Managed Keys

### Risk Level

Medium

### Address

Reliability, Security

### Compliance Standards

* GDPR
* HIPAA
* HITRUST CSF
* ISO 27001
* NIST CSF
* PCI
* SOC2
* Securities and Exchange Board of India (SEBI) - Cloud Security Adoption Framework

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        To remediate the misconfiguration of Spanner Database Backup not being encrypted with customer-managed keys in GCP, follow these steps:

        1. Go to the GCP Console and navigate to the Spanner instance whose backup you want to encrypt.

        2. Click on the "Backups" tab in the left-hand menu.

        3. Find the backup that needs to be encrypted and click on its name.

        4. Click on the "Encryption" tab in the top menu.

        5. Click on the "Edit" button.

        6. Select "Customer-managed key" from the "Encryption type" dropdown.

        7. Choose the appropriate key from the "Key name" dropdown.

        8. Click on the "Save" button to save the changes.

        9. Verify that the backup is now encrypted with the customer-managed key by checking the "Encryption" tab.

        10. Repeat these steps for any other Spanner backups that need to be encrypted with customer-managed keys.

        By following these steps, you can remediate the misconfiguration of Spanner Database Backup not being encrypted with customer-managed keys in GCP.

        #
      </Accordion>

      <Accordion title="Using CLI">
        To remediate this misconfiguration in GCP, you can follow these steps using GCP CLI:

        1. First, you need to create a new key ring and key using the following command:

           ```
           gcloud kms keyrings create [KEY_RING_NAME] --location [LOCATION]
           gcloud kms keys create [KEY_NAME] --location [LOCATION] --keyring [KEY_RING_NAME] --purpose encryption
           ```

           Replace `[KEY_RING_NAME]`, `[LOCATION]`, and `[KEY_NAME]` with your own values.

        2. Next, you need to grant the Cloud Spanner service account permission to use the key by adding the `cloudkms.cryptoKeyEncrypterDecrypter` role to the service account. You can use the following command:

           ```
           gcloud projects add-iam-policy-binding [PROJECT_ID] --member serviceAccount:[SERVICE_ACCOUNT_EMAIL] --role roles/cloudkms.cryptoKeyEncrypterDecrypter --condition=None
           ```

           Replace `[PROJECT_ID]` and `[SERVICE_ACCOUNT_EMAIL]` with your own values.

        3. Now, you need to configure Cloud Spanner to use the customer-managed encryption key by updating the backup configuration. You can use the following command:

           ```
           gcloud spanner backups update [BACKUP_ID] --encryption-config kms-key-name=[KEY_NAME] --encryption-type customer-managed
           ```

           Replace `[BACKUP_ID]` and `[KEY_NAME]` with your own values.

        4. Finally, you need to verify that the backup configuration has been updated successfully by running the following command:

           ```
           gcloud spanner backups describe [BACKUP_ID]
           ```

           This command should return the details of the backup configuration, including the encryption configuration.

        By following these steps, you can remediate the misconfiguration and ensure that your Spanner database backups are encrypted with customer-managed keys in GCP.
      </Accordion>

      <Accordion title="Using Python">
        To remediate the misconfiguration "Spanner Database Backup Should Be Encrypted With Customer Managed Keys" for GCP using Python, you can follow these steps:

        1. Create a Customer Managed Encryption Key (CMEK) in Google Cloud KMS. This key will be used to encrypt the backups. You can use the following code to create a CMEK:

        ```python theme={null}
        from google.cloud import kms_v1
        from google.cloud.kms_v1 import enums

        client = kms_v1.KeyManagementServiceClient()

        # Set the Key Ring and Key ID
        key_ring_id = 'your-key-ring-id'
        key_id = 'your-key-id'

        # Set the Key Purpose
        purpose = enums.CryptoKey.CryptoKeyPurpose.ENCRYPT_DECRYPT

        # Create the Key
        parent = client.key_ring_path('[PROJECT]', key_ring_id)
        response = client.create_crypto_key(parent, key_id, {'purpose': purpose})
        print('Created key: {}'.format(response.name))
        ```

        2. Enable backup encryption for your Spanner instance. You can use the following code to enable backup encryption:

        ```python theme={null}
        from google.cloud import spanner_admin_database_v1

        # Set the instance and database IDs
        instance_id = 'your-instance-id'
        database_id = 'your-database-id'

        # Set the backup configuration
        backup_config = {
            'encryption_config': {
                'kms_key_name': 'projects/[PROJECT]/locations/[LOCATION]/keyRings/[KEYRING]/cryptoKeys/[KEY]'
            }
        }

        # Update the backup configuration
        database_admin_client = spanner_admin_database_v1.DatabaseAdminClient()
        database_name = database_admin_client.database_path('[PROJECT]', instance_id, database_id)
        operation = database_admin_client.update_backup(database_name, backup_config)
        print('Backup encryption enabled: {}'.format(operation))
        ```

        3. Verify that backup encryption is enabled for your Spanner instance. You can use the following code to verify backup encryption:

        ```python theme={null}
        from google.cloud import spanner_admin_database_v1

        # Set the instance and database IDs
        instance_id = 'your-instance-id'
        database_id = 'your-database-id'

        # Get the database backup configuration
        database_admin_client = spanner_admin_database_v1.DatabaseAdminClient()
        database_name = database_admin_client.database_path('[PROJECT]', instance_id, database_id)
        backup_info = database_admin_client.get_backup_info(database_name)
        print('Backup encryption enabled: {}'.format(backup_info.encryption_info.encryption_type))
        ```

        This will ensure that your Spanner database backups are encrypted with a customer-managed encryption key in Google Cloud KMS.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        resource "google_spanner_backup" "SPANNER_BACKUP_NAME" {
          # Replace with your Spanner instance and database details
          instance     = "SPANNER_INSTANCE_ID"          # e.g. "my-spanner-instance"
          database     = "SPANNER_DATABASE_NAME"        # e.g. "db1"
          backup_id    = "SPANNER_BACKUP_ID"            # e.g. "db1-backup-20240727"
          expire_time  = "2026-12-31T23:59:59Z"

          # Use a customer-managed Cloud KMS key for encryption
          kms_key_name = "projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/CRYPTO_KEY"
          # - PROJECT_ID:     KMS project (can be different from Spanner project if IAM allows)
          # - LOCATION:       Must match the Spanner instance / database region
          # - KEY_RING:       Existing key ring name
          # - CRYPTO_KEY:     Existing key name
        }
        ```

        Using a KMS key for an existing backup requires creating a new backup; Terraform will show this as `google_spanner_backup.SPANNER_BACKUP_NAME` being replaced, which deletes the old backup and creates a new CMEK‑encrypted one (backups are immutable).

        For verification, `terraform plan` should show `kms_key_name` being added (or changed) on the `google_spanner_backup` resource, and if it was previously unencrypted or using Google‑managed keys, the resource will be marked for replacement.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
