This check flags Compute Engine boot disks encrypted with Google-managed keys instead of customer-managed encryption keys (CMEK). Without CMEK you lose control over key rotation, revocation, and audit. Fix it by creating a Cloud KMS key and recreating the disk with --disk=...,kms-key=... or attaching CMEK in your Terraform disk config.
By default, every Compute Engine disk is encrypted at rest. Google handles the keys for you, rotates them, and never lets the data sit unencrypted on physical media. That covers the basic compliance box for encryption at rest, but it leaves one thing out of your hands: the key itself. With Google-managed encryption you cannot rotate the key on your own schedule, you cannot revoke access during an incident, and you cannot prove in an audit that a specific key protects a specific disk.
The VM Disk Not Using Customer-Managed Key check looks for boot disks that rely on default Google-managed encryption rather than a customer-managed encryption key (CMEK) backed by Cloud KMS. For workloads handling regulated or sensitive data, that gap matters.
What this check detects
The check inspects each Compute Engine VM and reads the encryption configuration on its boot disk. If the disk has no diskEncryptionKey.kmsKeyName set, it is using Google's default encryption and the check fails.
Concretely, a disk passes when its configuration includes a reference to a Cloud KMS key, like this:
{
"name": "instance-1",
"disks": [
{
"boot": true,
"diskEncryptionKey": {
"kmsKeyName": "projects/my-project/locations/us-central1/keyRings/vm-keyring/cryptoKeys/boot-disk-key"
}
}
]
}
If diskEncryptionKey is absent or only contains a Google-managed indicator, Lensix raises the finding compute_nodiskencryption.
Note: CMEK does not change how the data is encrypted on disk. The disk is still encrypted with an AES-256 data encryption key (DEK). What changes is that the DEK is wrapped by a key you own in Cloud KMS (the KEK), so Compute Engine cannot read the disk unless your KMS key is available and accessible.
Why it matters
Default encryption protects you against one threat: someone physically stealing a drive out of a Google data center. That is a real protection, but it is not the threat most teams worry about. CMEK addresses the operational and governance risks that come up far more often.
You can revoke access during an incident
If you suspect a VM is compromised or an attacker has gained a foothold in a project, disabling or revoking the KMS key version makes the disk unreadable almost immediately. New reads fail, and you have bought yourself time to investigate. With Google-managed keys you have no equivalent kill switch.
You control rotation on your own schedule
Many compliance frameworks (PCI DSS, HIPAA-aligned programs, FedRAMP) expect documented key rotation policies. CMEK lets you set automatic rotation in Cloud KMS, for example every 90 days, and prove it. Google-managed rotation happens, but you do not control or attest to the schedule.
You get a clean audit trail
Every use of a CMEK key generates Cloud Audit Logs entries in Cloud KMS. You can see which service account decrypted which disk and when. That visibility is the difference between "the data was encrypted" and "here is exactly who touched the key protecting this data."
Warning: CMEK comes with operational weight. If you delete the key version or remove the Compute Engine service agent's permission to use it, every disk wrapped by that key becomes unreadable and the VMs will fail to boot or attach disks. Treat key lifecycle as production-critical.
How to fix it
You cannot retroactively switch an existing disk from Google-managed encryption to CMEK in place. The encryption choice is set at disk creation. The fix is to create a CMEK-protected disk and migrate the workload onto it. Here is the full path.
Step 1: Create a key ring and key in Cloud KMS
Pick a location that matches the region of your VMs. Key location and disk location must be compatible.
gcloud kms keyrings create vm-keyring \
--location=us-central1
gcloud kms keys create boot-disk-key \
--location=us-central1 \
--keyring=vm-keyring \
--purpose=encryption \
--rotation-period=90d \
--next-rotation-time=$(date -u -d "+90 days" +%Y-%m-%dT%H:%M:%SZ)
Step 2: Grant the Compute Engine service agent access to the key
Compute Engine uses a per-project service agent to wrap and unwrap disk keys. It needs the cloudkms.cryptoKeyEncrypterDecrypter role on the key.
PROJECT_NUMBER=$(gcloud projects describe "$(gcloud config get-value project)" \
--format='value(projectNumber)')
gcloud kms keys add-iam-policy-binding boot-disk-key \
--location=us-central1 \
--keyring=vm-keyring \
--member="serviceAccount:service-${PROJECT_NUMBER}@compute-system.iam.gserviceaccount.com" \
--role="roles/cloudkms.cryptoKeyEncrypterDecrypter"
Note: The [email protected] agent is created automatically the first time you use Compute Engine in a project. If the binding fails because the account does not exist yet, create any disk or VM first, then retry.
Step 3: Create a new VM (or disk) with CMEK
For a fresh VM, point the boot disk at your KMS key:
gcloud compute instances create instance-cmek \
--zone=us-central1-a \
--image-family=debian-12 \
--image-project=debian-cloud \
--create-disk=auto-delete=yes,boot=yes,kms-key=projects/$(gcloud config get-value project)/locations/us-central1/keyRings/vm-keyring/cryptoKeys/boot-disk-key
To migrate an existing workload, snapshot the old disk, create a CMEK-encrypted disk from the snapshot, then swap it onto the instance:
Danger: Detaching and replacing a boot disk requires stopping the VM and will cause downtime. Run this on the affected instance during a maintenance window, and confirm you have a working snapshot before deleting anything.
# Stop the VM
gcloud compute instances stop instance-1 --zone=us-central1-a
# Snapshot the existing boot disk
gcloud compute snapshots create instance-1-snap \
--source-disk=instance-1 \
--source-disk-zone=us-central1-a
# Create a CMEK-encrypted disk from the snapshot
gcloud compute disks create instance-1-cmek \
--zone=us-central1-a \
--source-snapshot=instance-1-snap \
--kms-key=projects/$(gcloud config get-value project)/locations/us-central1/keyRings/vm-keyring/cryptoKeys/boot-disk-key
# Detach old disk, attach the new CMEK disk as boot
gcloud compute instances detach-disk instance-1 \
--disk=instance-1 --zone=us-central1-a
gcloud compute instances attach-disk instance-1 \
--disk=instance-1-cmek --boot --zone=us-central1-a
# Restart
gcloud compute instances start instance-1 --zone=us-central1-a
Terraform example
If you manage infrastructure as code, set the CMEK on the boot disk directly. This is the cleaner long-term approach because new VMs get CMEK automatically.
resource "google_kms_key_ring" "vm" {
name = "vm-keyring"
location = "us-central1"
}
resource "google_kms_crypto_key" "boot_disk" {
name = "boot-disk-key"
key_ring = google_kms_key_ring.vm.id
rotation_period = "7776000s" # 90 days
}
resource "google_compute_instance" "vm" {
name = "instance-cmek"
machine_type = "e2-medium"
zone = "us-central1-a"
boot_disk {
initialize_params {
image = "debian-cloud/debian-12"
}
kms_key_self_link = google_kms_crypto_key.boot_disk.id
}
network_interface {
network = "default"
}
}
Tip: Wire the IAM binding into the same Terraform so the Compute Engine service agent always has access before the disk is created. Use google_project_service_identity for the compute service agent and a google_kms_crypto_key_iam_member resource granting roles/cloudkms.cryptoKeyEncrypterDecrypter. That removes the manual Step 2 entirely.
How to prevent it from happening again
Manual remediation does not scale. The goal is to make CMEK the only way a VM disk can be created. Two layers work well together.
Organization Policy constraint
Google Cloud has a built-in constraint that denies resource creation unless a CMEK is provided. Apply it at the organization or folder level so it covers every project.
gcloud resource-manager org-policies enable-enforce \
constraints/gcp.restrictNonCmekServices \
--organization=ORGANIZATION_ID
You can also use constraints/gcp.restrictCmekCryptoKeyProjects to limit which projects' keys are allowed, which prevents teams from pointing disks at keys outside an approved key management project.
Policy-as-code in CI/CD
Catch the problem before it ever reaches the cloud. A Terraform plan check with OPA or Conftest can fail the pipeline when a google_compute_instance boot disk lacks kms_key_self_link.
package main
deny[msg] {
resource := input.resource_changes[_]
resource.type == "google_compute_instance"
disk := resource.change.after.boot_disk[_]
not disk.kms_key_self_link
msg := sprintf("Instance '%s' boot disk must use a customer-managed key (kms_key_self_link)", [resource.address])
}
Tip: Run this against terraform show -json tfplan.binary output in your pull request pipeline. Developers see the failure in code review instead of getting a flagged finding after deploy, which is a much shorter feedback loop.
Best practices
- Separate key management from workloads. Keep Cloud KMS keys in a dedicated project with tightly controlled IAM. The team running VMs should be able to use the key, not manage or delete it.
- Enable automatic rotation. Set a rotation period (90 days is a common baseline) so new data is wrapped with fresh key versions without manual effort.
- Match key location to disk location. A regional key cannot encrypt a disk in a different region. Decide your regional strategy before rolling CMEK out broadly.
- Protect against accidental key deletion. Cloud KMS keys cannot be hard-deleted immediately; versions enter a scheduled-for-destruction state. Use that window, and restrict
cloudkms.cryptoKeyVersions.destroyto break-glass roles only. - Apply CMEK to all disks, not just boot disks. Attached data disks hold the sensitive payloads. Extend the same KMS key configuration to every persistent disk.
- Monitor key usage. Send Cloud KMS audit logs to a sink and alert on unexpected decrypt calls or permission changes on the key.
Warning: CMEK adds a small per-operation Cloud KMS cost and a dependency on KMS availability. For high-throughput disk operations the cost stays low, but plan key access carefully in multi-region or disaster recovery designs so a key in one region does not become a single point of failure for a workload elsewhere.
Switching VM disks to customer-managed keys is a one-time setup that pays off every time you face an audit, an incident response, or a rotation requirement. Get the org policy and CI gate in place, and the finding stops coming back.

