Back to Checks
gcp

Cloud SQL instance is encrypted with a customer-managed key (CMEK)

cloudsql_instance_cmek_encryption_enabled
Service: cloudsqlSeverity: medium
OfficialBuilt-inVerified
Categories:encryption
Resource Type:sqladmin.googleapis.com/Instance

Cloud SQL instances use customer-managed encryption keys (CMEK) via Cloud KMS for at-rest encryption. The evaluation identifies instances lacking a configured Cloud KMS key, indicating use of default Google-managed encryption instead.

Risk

Without CMEK, Google holds sole control of the encryption keys. If the organization must demonstrate key custody, meet data residency requirements, or immediately revoke access to data (e.g., upon contract termination), Google-managed keys are insufficient. This may violate ISMS-P 2.7.1 and regulatory requirements for sensitive or personal data.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler gcp --checks cloudsql_instance_cmek_encryption_enabled

Recommendation

For instances storing personal or sensitive data, create new Cloud SQL instances with CMEK using a Cloud KMS key in the same region. Ensure the Cloud SQL service account has the roles/cloudkms.cryptoKeyEncrypterDecrypter role on the key, and enable key rotation per your policy.

Remediation

CLI

gcloud sql instances create <INSTANCE_NAME> \
  --database-version=<DATABASE_VERSION> \
  --region=<REGION> \
  --disk-encryption-key=projects/<PROJECT>/locations/<REGION>/keyRings/<RING>/cryptoKeys/<KEY>

Terraform

resource "google_sql_database_instance" "example" {
  name             = "<instance_name>"
  database_version = "<database_version>"
  region           = "<region>"

  encryption_key_name = "projects/<project>/locations/<region>/keyRings/<ring>/cryptoKeys/<key>"

  settings {
    tier = "db-custom-2-7680"
  }
}

Other

1CMEK must be configured at instance creation time. To migrate an existing instance:
2Create a new Cloud SQL instance with CMEK enabled.
3Export data from the existing instance.
4Import data into the new CMEK-enabled instance.
5Update application connection strings.

Check Code

from prowler.lib.check.models import Check, Check_Report_GCP
from prowler.providers.gcp.services.cloudsql.cloudsql_client import cloudsql_client


class cloudsql_instance_cmek_encryption_enabled(Check):
    def execute(self) -> Check_Report_GCP:
        findings = []
        for instance in cloudsql_client.instances:
            if instance.instance_type != "CLOUD_SQL_INSTANCE":
                continue
            report = Check_Report_GCP(metadata=self.metadata(), resource=instance)
            if instance.cmek_key_name:
                report.status = "PASS"
                report.status_extended = (
                    f"Database instance {instance.name} is encrypted with "
                    f"customer-managed key: {instance.cmek_key_name}."
                )
            else:
                report.status = "FAIL"
                report.status_extended = (
                    f"Database instance {instance.name} is not encrypted with a "
                    f"customer-managed key (CMEK); Google-managed key is in use."
                )
            findings.append(report)
        return findings