> ## 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.

# SQL Instances Should Be Encrypted Using Customer Managed Keys (CMKs)

### More Info:

Ensure that SQL Instances are encrypted using Customer Managed Keys (CMKs).

### Risk Level

Medium

### Address

Security

### Compliance Standards

* APRA CPS 234 (Australia)
* BSI C5 (Germany)
* Brazil LGPD
* CCPA / CPRA (California)
* CIS Critical Security Controls v8
* CMMC 2.0
* CSA Cloud Controls Matrix v4
* DPDPA
* Digital Operational Resilience Act (EU)
* GDPR
* HITRUST CSF
* ISO/IEC 27017
* ISO/IEC 27018
* ISO/IEC 27701
* KSA PDPL
* MAS Technology Risk Management (Singapore)
* MITRE ATT\&CK (Cloud)
* NIS2 Directive
* NIST CSF
* NIST SP 800-171
* NYDFS 23 NYCRR 500
* PCI
* SOC2
* SWIFT Customer Security Controls Framework
* Sarbanes-Oxley IT General Controls
* Securities and Exchange Board of India (SEBI) - Cloud Security Adoption Framework
* UK NCSC Cyber Assessment Framework

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        Sure! Here are the step by step instructions to remediate the misconfiguration "SQL Instances Should Be Encrypted Using Customer Managed Keys (CMKs)" for GCP using GCP console:

        1. Open the GCP console and navigate to the Cloud SQL instances page.
        2. Select the SQL instance that you want to encrypt.
        3. Click on the "Edit" button at the top of the page.
        4. Scroll down to the "Encryption" section and select the option "Customer-managed key".
        5. Choose the key ring and key that you want to use for encryption. If you don't have a key, create one by clicking on the "Create" button.
        6. Click on the "Save" button to save the changes.

        Once you have completed these steps, your SQL instance will be encrypted using the customer-managed key that you selected. It is important to note that this process requires the appropriate permissions to create and manage keys in your GCP project.

        #
      </Accordion>

      <Accordion title="Using CLI">
        To remediate the misconfiguration of SQL instances not being encrypted using customer managed keys (CMKs) in GCP using GCP CLI, follow these steps:

        1. Open the Cloud Shell in the GCP console.

        2. Use the following command to list all the Cloud SQL instances in your project:

           ```
           gcloud sql instances list
           ```

        3. Choose the instance that you want to encrypt and note down its instance name.

        4. Use the following command to encrypt the SQL instance using a customer-managed encryption key:

           ```
           gcloud sql instances patch [INSTANCE_NAME] --backup-start-time 02:00 --require-ssl --storage-auto-increase --storage-size [SIZE] --storage-type [STORAGE_TYPE] --authorized-networks [NETWORK_NAME] --database-version [DATABASE_VERSION] --maintenance-window-day [DAY_OF_WEEK] --maintenance-window-hour [HOUR_OF_DAY] --maintenance-release-channel [RELEASE_CHANNEL] --encryption-key-name [KEY_NAME]
           ```

           Replace `[INSTANCE_NAME]` with the name of your SQL instance, `[SIZE]` with the desired storage size in GB, `[STORAGE_TYPE]` with the desired storage type, `[NETWORK_NAME]` with the name of the authorized network, `[DATABASE_VERSION]` with the desired database version, `[DAY_OF_WEEK]` with the preferred day of the week for maintenance, `[HOUR_OF_DAY]` with the preferred hour of the day for maintenance, `[RELEASE_CHANNEL]` with the preferred release channel for maintenance, and `[KEY_NAME]` with the name of the customer-managed encryption key.

        5. Once you have executed the command, the SQL instance will be encrypted using the customer-managed encryption key.

        6. Verify the encryption status of the SQL instance using the following command:

           ```
           gcloud sql instances describe [INSTANCE_NAME]
           ```

           You should see the `encryptionKeyName` property set to the name of your customer-managed encryption key.

        By following these steps, you can remediate the misconfiguration of SQL instances not being encrypted using customer-managed keys (CMKs) in GCP using GCP CLI.
      </Accordion>

      <Accordion title="Using Python">
        To remediate the misconfiguration of SQL instances not being encrypted using customer-managed keys (CMKs) in GCP, you can use the following steps:

        1. Create a new Cloud KMS key ring and key to use as the CMK. You can do this using the following Python code:

        ```
        from google.cloud import kms_v1

        kms_client = kms_v1.KeyManagementServiceClient()

        parent = kms_client.key_ring_path(project_id, location_id, key_ring_id)

        response = kms_client.create_crypto_key(parent, crypto_key_id, kms_v1.CryptoKey())

        print(f'Created key {response.name}')
        ```

        Replace `project_id`, `location_id`, `key_ring_id`, and `crypto_key_id` with your own values.

        2. Update the SQL instance to use the newly created CMK. You can do this using the following Python code:

        ```
        from google.cloud import sql_v1beta4

        sql_client = sql_v1beta4.CloudSqlInstanceServiceClient()

        instance_name = f'projects/{project_id}/instances/{instance_id}'

        settings = sql_v1beta4.Settings()

        settings.ip_configuration.require_ssl = True
        settings.ip_configuration.authorized_networks.enabled = True

        encryption_settings = sql_v1beta4.EncryptionSettings()

        encryption_settings.kms_key_name = f'projects/{project_id}/locations/{location_id}/keyRings/{key_ring_id}/cryptoKeys/{crypto_key_id}'

        settings.encryption_configuration = encryption_settings

        request = sql_v1beta4.SqlInstancesUpdateRequest(instance=instance_name, project=project_id, body={'settings': settings})

        response = sql_client.update(request=request)

        print(f'Updated instance {instance_name} with encryption settings')
        ```

        Replace `project_id`, `instance_id`, `location_id`, `key_ring_id`, and `crypto_key_id` with your own values.

        3. Verify that the SQL instance is now using the CMK for encryption. You can do this using the following Python code:

        ```
        response = sql_client.get(instance_name)

        encryption_settings = response.settings.encryption_configuration

        print(f'Instance {instance_name} is now using CMK {encryption_settings.kms_key_name} for encryption')
        ```

        Replace `instance_name` with your own value.

        These steps will remediate the misconfiguration of SQL instances not being encrypted using customer-managed keys (CMKs) in GCP.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        # Customer-managed key (CMK) used to encrypt the Cloud SQL instance
        resource "google_kms_crypto_key" "SQL_CMK" {
          name            = "SQL_CMK_NAME"                    # replace with your key name
          key_ring        = "projects/PROJECT_ID/locations/KMS_LOCATION/keyRings/KEY_RING_NAME"
          rotation_period = "7776000s"                        # 90 days; adjust as needed

          purpose = "ENCRYPT_DECRYPT"
        }

        # Allow the Cloud SQL service account to use the CMK
        resource "google_kms_crypto_key_iam_binding" "sql_cmk_binding" {
          crypto_key_id = google_kms_crypto_key.SQL_CMK.id
          role          = "roles/cloudkms.cryptoKeyEncrypterDecrypter"

          members = [
            "serviceAccount:SQL_SERVICE_ACCOUNT@PROJECT_ID.iam.gserviceaccount.com", # replace with the actual Cloud SQL service account
          ]
        }

        # Cloud SQL instance encrypted with the CMK
        resource "google_sql_database_instance" "CLOUD_SQL_INSTANCE" {
          name             = "SQL_INSTANCE_NAME"           # replace with your instance name
          database_version = "MYSQL_8_0"                   # replace with your engine/version
          region           = "SQL_REGION"                  # replace with your region

          # IMPORTANT: Changing this block on an existing instance forces replacement.
          disk_encryption_configuration {
            kms_key_name = google_kms_crypto_key.SQL_CMK.id
          }

          settings {
            tier = "db-custom-2-7680"                      # replace with your tier

            # ...other settings as required...
          }

          # ...other arguments as required...
        }
        ```

        Switching an existing `google_sql_database_instance` to use a CMK via `disk_encryption_configuration.kms_key_name` forces the instance to be destroyed and re-created, so plan for downtime and data migration before applying.

        Verification: `terraform plan` should show `disk_encryption_configuration.kms_key_name` set on the `google_sql_database_instance` (and a replacement of the instance if it already exists), plus creation of the KMS key and IAM binding if they are new.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
