Encrypting data at rest is a fundamental security control that protects your information even if storage media is compromised or accidentally exposed. While Google Cloud encrypts all data by default, understanding and implementing Customer-Managed Encryption Keys (CMEK) provides additional control for compliance requirements and defense-in-depth security.
This guide covers encryption implementation across major GCP services. For foundational cloud security practices, see our 30 Cloud Security Tips for 2026 guide, specifically Tip 4 on encrypting data at rest.
Understanding GCP Encryption Options
GCP provides three encryption approaches:
- Google-Managed Keys (GMEK) - Default, automatic, no configuration required
- Customer-Managed Keys (CMEK) - You control keys in Cloud KMS
- Customer-Supplied Keys (CSEK) - You provide keys for each request (Compute Engine only)
This guide focuses on CMEK as the recommended approach for organizations requiring key control.
Step 1: Set Up Cloud KMS for Key Management
Before encrypting resources, create a key ring and crypto key in Cloud KMS:
Via Google Cloud Console
-
- Navigate to [Security > Key Management](https://console.cloud.google.com/security/kms)
- Click **Create Key Ring**
- Configure the key ring:
-
Key ring name:
production-keys -
Key ring location: Match your resource location (e.g.,
us-central1) -
Click Create
-
Click Create Key within the key ring
-
Configure the key:
-
Key name:
storage-encryption-key -
Protection level: Software (or HSM for FIPS 140-2 Level 3)
-
Purpose: Symmetric encrypt/decrypt
-
Rotation period: 90 days (recommended)
-
Click Create
Via gcloud CLI
# Create a key ring
gcloud kms keyrings create production-keys \
--location=us-central1 \
--project=PROJECT_ID
# Create a symmetric encryption key
gcloud kms keys create storage-encryption-key \
--location=us-central1 \
--keyring=production-keys \
--purpose=encryption \
--rotation-period=7776000s \
--next-rotation-time=$(date -u -v+90d +"%Y-%m-%dT%H:%M:%SZ") \
--project=PROJECT_IDVia Terraform
resource "google_kms_key_ring" "production_keys" {
name = "production-keys"
location = "us-central1"
project = var.project_id
}
resource "google_kms_crypto_key" "storage_key" {
name = "storage-encryption-key"
key_ring = google_kms_key_ring.production_keys.id
rotation_period = "7776000s" # 90 days
lifecycle {
prevent_destroy = true
}
version_template {
algorithm = "GOOGLE_SYMMETRIC_ENCRYPTION"
protection_level = "SOFTWARE"
}
}
# Grant Cloud Storage service account access to the key
resource "google_kms_crypto_key_iam_member" "storage_encrypter" {
crypto_key_id = google_kms_crypto_key.storage_key.id
role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
member = "serviceAccount:service-${var.project_number}@gs-project-accounts.iam.gserviceaccount.com"
}Step 2: Encrypt Cloud Storage with CMEK
Configure Cloud Storage buckets to use your CMEK:
Grant Service Account Access
Cloud Storage needs permission to use your key:
# Get your project's Cloud Storage service account
gcloud storage service-agent --project=PROJECT_ID
# Grant the service account encrypter/decrypter access
gcloud kms keys add-iam-policy-binding storage-encryption-key \
--location=us-central1 \
--keyring=production-keys \
--member="serviceAccount:service-PROJECT_NUMBER@gs-project-accounts.iam.gserviceaccount.com" \
--role="roles/cloudkms.cryptoKeyEncrypterDecrypter" \
--project=PROJECT_IDCreate Bucket with CMEK
# Create bucket with default CMEK encryption
gcloud storage buckets create gs://my-encrypted-bucket \
--location=us-central1 \
--default-encryption-key=projects/PROJECT_ID/locations/us-central1/keyRings/production-keys/cryptoKeys/storage-encryption-key \
--project=PROJECT_IDVia Console
-
- Navigate to [Cloud Storage](https://console.cloud.google.com/storage/browser)
- Click **Create Bucket**
- Under **Advanced settings > Encryption**, select **Customer-managed encryption key**
- Select your key from Cloud KMS
- Complete bucket creation
Terraform Example
resource "google_storage_bucket" "encrypted_bucket" {
name = "my-encrypted-bucket-${var.project_id}"
location = "US-CENTRAL1"
storage_class = "STANDARD"
encryption {
default_kms_key_name = google_kms_crypto_key.storage_key.id
}
uniform_bucket_level_access = true
versioning {
enabled = true
}
depends_on = [google_kms_crypto_key_iam_member.storage_encrypter]
}Step 3: Encrypt Compute Engine Disks
Configure persistent disk encryption with CMEK:
Grant Compute Engine Access
# Get the Compute Engine service account
gcloud projects describe PROJECT_ID --format="value(projectNumber)"
# Grant access (service account format: [email protected])
gcloud kms keys add-iam-policy-binding storage-encryption-key \
--location=us-central1 \
--keyring=production-keys \
--member="serviceAccount:[email protected]" \
--role="roles/cloudkms.cryptoKeyEncrypterDecrypter" \
--project=PROJECT_IDCreate Encrypted Disk
# Create a disk with CMEK
gcloud compute disks create encrypted-disk \
--size=100GB \
--type=pd-ssd \
--zone=us-central1-a \
--kms-key=projects/PROJECT_ID/locations/us-central1/keyRings/production-keys/cryptoKeys/storage-encryption-key \
--project=PROJECT_ID
# Create VM with encrypted boot disk
gcloud compute instances create encrypted-vm \
--zone=us-central1-a \
--machine-type=e2-medium \
--boot-disk-kms-key=projects/PROJECT_ID/locations/us-central1/keyRings/production-keys/cryptoKeys/storage-encryption-key \
--project=PROJECT_IDVia Console
-
- Navigate to [Compute Engine > Disks](https://console.cloud.google.com/compute/disks)
- Click **Create Disk**
- Under **Encryption**, select **Customer-managed encryption key**
- Select your Cloud KMS key
- Click **Create**
Terraform Example
resource "google_compute_disk" "encrypted_disk" {
name = "encrypted-disk"
type = "pd-ssd"
zone = "us-central1-a"
size = 100
disk_encryption_key {
kms_key_self_link = google_kms_crypto_key.storage_key.id
}
}
resource "google_compute_instance" "encrypted_vm" {
name = "encrypted-vm"
machine_type = "e2-medium"
zone = "us-central1-a"
boot_disk {
initialize_params {
image = "debian-cloud/debian-11"
}
kms_key_self_link = google_kms_crypto_key.storage_key.id
}
network_interface {
network = "default"
}
}Step 4: Encrypt Cloud SQL Databases
Configure Cloud SQL with CMEK:
Grant Cloud SQL Access
# Get the Cloud SQL service account
gcloud sql instances describe INSTANCE_NAME --format="value(serviceAccountEmailAddress)"
# Grant access to the KMS key
gcloud kms keys add-iam-policy-binding storage-encryption-key \
--location=us-central1 \
--keyring=production-keys \
--member="serviceAccount:SERVICE_ACCOUNT_EMAIL" \
--role="roles/cloudkms.cryptoKeyEncrypterDecrypter" \
--project=PROJECT_IDCreate Encrypted Cloud SQL Instance
# Create MySQL instance with CMEK
gcloud sql instances create encrypted-mysql \
--database-version=MYSQL_8_0 \
--tier=db-n1-standard-2 \
--region=us-central1 \
--disk-encryption-key=projects/PROJECT_ID/locations/us-central1/keyRings/production-keys/cryptoKeys/storage-encryption-key \
--project=PROJECT_ID
# Create PostgreSQL instance with CMEK
gcloud sql instances create encrypted-postgres \
--database-version=POSTGRES_15 \
--tier=db-custom-2-7680 \
--region=us-central1 \
--disk-encryption-key=projects/PROJECT_ID/locations/us-central1/keyRings/production-keys/cryptoKeys/storage-encryption-key \
--project=PROJECT_IDVia Console
-
- Navigate to [SQL](https://console.cloud.google.com/sql)
- Click **Create Instance**
- Choose your database engine
- Under **Customize your instance > Data Protection**, expand settings
- Check **Use a customer-managed encryption key**
- Select your Cloud KMS key
- Complete instance creation
Terraform Example
resource "google_sql_database_instance" "encrypted_postgres" {
name = "encrypted-postgres"
database_version = "POSTGRES_15"
region = "us-central1"
encryption_key_name = google_kms_crypto_key.storage_key.id
settings {
tier = "db-custom-2-7680"
backup_configuration {
enabled = true
}
ip_configuration {
ipv4_enabled = false
private_network = google_compute_network.private_network.id
}
}
deletion_protection = true
}Step 5: Implement Key Rotation Policies
Configure automatic key rotation for compliance:
Set Rotation Schedule
# Update key rotation schedule
gcloud kms keys update storage-encryption-key \
--location=us-central1 \
--keyring=production-keys \
--rotation-period=7776000s \
--next-rotation-time=$(date -u -v+90d +"%Y-%m-%dT%H:%M:%SZ") \
--project=PROJECT_IDManual Key Rotation
# Create new key version immediately
gcloud kms keys versions create \
--key=storage-encryption-key \
--location=us-central1 \
--keyring=production-keys \
--primary \
--project=PROJECT_IDNote: When a key is rotated, new data is encrypted with the new version. Existing data remains encrypted with the original key version and is automatically decrypted using that version when accessed.
Step 6: Monitor Encryption Status
Verify encryption configuration across resources:
Check Cloud Storage Encryption
# List bucket encryption configuration
gcloud storage buckets describe gs://my-bucket --format="yaml(encryption)"
# Check object encryption
gcloud storage objects describe gs://my-bucket/my-object --format="yaml(kmsKeyName)"Check Compute Engine Disk Encryption
# List disk encryption
gcloud compute disks describe encrypted-disk \
--zone=us-central1-a \
--format="yaml(diskEncryptionKey)"Audit Key Usage
# View key usage in Cloud Audit Logs
gcloud logging read "protoPayload.serviceName=cloudkms.googleapis.com" \
--limit=50 \
--project=PROJECT_IDBest Practices for Data Encryption
- Use separate keys per environment - Production, staging, and development should use different keys
- Match key location to data location - Keys must be in the same region as the data they encrypt
- Enable automatic key rotation - 90 days is recommended for most compliance frameworks
- Use HSM-backed keys for sensitive data - FIPS 140-2 Level 3 compliance when required
- Implement key access logging - Monitor who accesses keys and when
- Protect keys with VPC Service Controls - Prevent key exfiltration
- Test key destruction procedures - Understand the 24-hour pending deletion window
Related Resources
- 30 Cloud Security Tips for 2026 - Comprehensive cloud security guide
- GCP Secret Manager Tutorial - Managing secrets and credentials
- Secure Cloud SQL Access - Database security practices
- Cloud KMS Documentation
- Cloud Storage Encryption Documentation
Need help implementing encryption policies across your Google Cloud environment? Contact InventiveHQ for expert guidance on data protection and compliance.