Google Cloudintermediate

GCP Storage Encryption Guide: Protecting Data at Rest

Complete guide to encrypting data at rest in Google Cloud. Covers Cloud Storage encryption, CMEK configuration, Compute Engine disk encryption, Cloud SQL encryption, and key management with Cloud KMS.

12 min readUpdated 2026-01-13

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_ID

Via 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_ID

Create 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_ID

Via 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_ID

Create 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_ID

Via 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_ID

Create 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_ID

Via 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_ID

Manual 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_ID

Note: 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_ID

Best 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

Need help implementing encryption policies across your Google Cloud environment? Contact InventiveHQ for expert guidance on data protection and compliance.

Frequently Asked Questions

Find answers to common questions

Yes, Google Cloud encrypts all data at rest by default using Google-managed encryption keys (GMEK). This includes Cloud Storage objects, Compute Engine persistent disks, Cloud SQL databases, and most other services. Default encryption uses AES-256 and requires no configuration. For additional control, you can use Customer-Managed Encryption Keys (CMEK) with Cloud KMS or Customer-Supplied Encryption Keys (CSEK) that you manage entirely.

Expert GCP Management

From architecture design to managed operations, we handle your Google Cloud infrastructure.