Back to Checks
gcp

BigQuery dataset is encrypted with Customer-Managed Keys (CMKs)

bigquery_dataset_cmk_encryption
Service: bigquerySeverity: high
OfficialBuilt-inVerified
Categories:encryption
Resource Type:bigquery.googleapis.com/Dataset

BigQuery datasets use Customer-Managed Encryption Keys (CMEK) rather than Google-managed encryption. The evaluation identifies datasets configured to use a customer-managed key for data-at-rest protection.

Risk

Without CMEK, organizations lose cryptographic control of data at rest, weakening confidentiality and access governance. Lack of custom key rotation, revocation (kill switch), and location control hinders incident response and may conflict with data-sovereignty requirements.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler gcp --checks bigquery_dataset_cmk_encryption

Recommendation

Protect datasets with CMEK via Cloud KMS:

  • Set a dataset or project default key
  • Align key location with dataset region
  • Enforce least privilege and separation of duties on key usage
  • Rotate keys and define revocation procedures
  • Audit key usage and use org policies to require CMEK

Remediation

CLI

bq update --default_kms_key projects/<KMS_PROJECT_ID>/locations/<LOCATION>/keyRings/<KEY_RING>/cryptoKeys/<KEY_NAME> --dataset <DATASET_ID>

Terraform

resource "google_bigquery_dataset" "<example_resource_name>" {
  dataset_id = "<example_resource_id>"
  location   = "<LOCATION>"

  # Critical: apply CMEK at the dataset level so the check passes
  default_encryption_configuration {
    kms_key_name = "projects/<KMS_PROJECT_ID>/locations/<LOCATION>/keyRings/<KEY_RING>/cryptoKeys/<KEY_NAME>" # Critical: sets CMEK
  }
}

Other

1In Google Cloud Console, go to BigQuery
2In Explorer, select your project and click the dataset <DATASET_ID>
3Click Edit details
4Under Encryption, select Customer-managed key and choose or paste the key: projects/<KMS_PROJECT_ID>/locations/<LOCATION>/keyRings/<KEY_RING>/cryptoKeys/<KEY_NAME>
5Click Save

Check Code

from prowler.lib.check.models import Check, Check_Report_GCP
from prowler.providers.gcp.services.bigquery.bigquery_client import bigquery_client


class bigquery_dataset_cmk_encryption(Check):
    def execute(self) -> Check_Report_GCP:
        findings = []
        for dataset in bigquery_client.datasets:
            report = Check_Report_GCP(metadata=self.metadata(), resource=dataset)
            report.status = "PASS"
            report.status_extended = f"Dataset {dataset.name} is encrypted with Customer-Managed Keys (CMKs)."
            if not dataset.cmk_encryption:
                report.status = "FAIL"
                report.status_extended = f"Dataset {dataset.name} is not encrypted with Customer-Managed Keys (CMKs)."
            findings.append(report)

        return findings