Skip to content

Envelope Encryption & CMEK — Cơ Chế Mã Hoá Tầng Bậc

Tại sao envelope encryption là nền tảng của cloud security

Mã hoá dữ liệu là bắt buộc trong cloud. Nhưng câu hỏi không phải "có mã hoá không" mà là "ai kiểm soát key". Và đây là nơi cloud encryption trở nên phức tạp.

Phương pháp naive là mã hoá mọi object với một master key. Vấn đề ngay lập tức: nếu rotate key đó, phải re-encrypt toàn bộ data. Với petabytes of data, đây là impractical. Nếu key bị compromise, toàn bộ data bị expose.

Envelope encryption giải quyết vấn đề scale bằng cách tách key management khỏi data encryption. Kết quả là một hệ thống mà bạn có thể:

  • Rotate key mã hoá mà không cần re-encrypt data
  • Revoke access cho một subset data cụ thể
  • Cấp quyền decrypt cho specific identities
  • Audit mọi key usage

Hầu như mọi cloud encryption đều dùng envelope encryption dưới một hình thức nào đó — Google, AWS, Azure đều vậy. CMEK trong GCP là customer-facing interface của mô hình này.


Internal model — DEK và KEK

Data Encryption Key (DEK)

DEK là key trực tiếp mã hoá data. Đặc điểm:

  • Sinh ngẫu nhiên tại thời điểm encrypt
  • Thường là AES-256-GCM key (256 bits)
  • Không bao giờ được lưu dạng plaintext — luôn luôn được wrap (encrypt) bởi KEK
  • Có thể unique per object (one DEK per file) hoặc per operation

Key Encryption Key (KEK)

KEK là key mã hoá DEK. Đặc điểm:

  • Được lưu và quản lý trong Cloud KMS
  • Không bao giờ rời Cloud KMS (ngay cả khi decrypt, quá trình diễn ra bên trong KMS)
  • Được protect bởi KMS's security infrastructure (physical access controls, HSM option)
  • Có thể rotate độc lập với data

Tại sao thiết kế hai tầng này?

Bài toán scale: Nếu dùng một key để encrypt tất cả data, khi rotate key đó phải re-encrypt toàn bộ data. Với 1PB data, một rotation cycle có thể mất nhiều ngày và consume significant compute.

Với envelope encryption:

  • DEK rotate từng object: Mỗi object có DEK riêng. Khi object được viết lại, DEK mới được tạo. Không cần re-encrypt toàn bộ archive data.
  • KEK rotate independently: Rotate KEK chỉ yêu cầu re-wrap (re-encrypt) DEKs, không phải re-encrypt data. Re-wrap là operation rất nhỏ (vài bytes), có thể làm lazily khi DEK được accessed tiếp theo.

Bài toán access control: Với envelope encryption, revoke access đến một subset data có thể đạt được bằng cách destroy hoặc disable specific DEK wrappers, mà không cần rotate toàn bộ key hierarchy.


Data flow chi tiết — Encryption

ENCRYPTION FLOW:
─────────────────────────────────────────────────────────────────

1. Generate DEK locally (trong service/application, không cần KMS):
   DEK = random_bytes(32)   # 256-bit AES key

2. Encrypt data với DEK (locally, không cần network call):
   ciphertext_data = AES-256-GCM.Encrypt(key=DEK, plaintext=data)

3. Wrap DEK bằng KMS (network call đến Cloud KMS):
   encrypted_DEK = KMS.Encrypt(
       key=projects/p/keyRings/r/cryptoKeys/my-kek,
       plaintext=DEK
   )
   # KMS trả về: ciphertext chứa DEK đã được wrap bởi KEK
   # KEK không bao giờ rời KMS — phép wrap xảy ra inside KMS

4. Store: (ciphertext_data, encrypted_DEK) cùng nhau
   # encrypted_DEK thường được store alongside ciphertext_data
   # hoặc trong metadata của object

Observation quan trọng: Bước 2 không cần network call — data được mã hoá locally bằng DEK. Chỉ DEK wrapping (bước 3) cần call KMS. Đây là lý do envelope encryption scale tốt cho large objects — bạn không phải truyền data qua KMS API.


Data flow chi tiết — Decryption

DECRYPTION FLOW:
─────────────────────────────────────────────────────────────────

1. Retrieve (ciphertext_data, encrypted_DEK) từ storage

2. Unwrap DEK qua KMS (network call):
   DEK_plaintext = KMS.Decrypt(
       key=projects/p/keyRings/r/cryptoKeys/my-kek,
       ciphertext=encrypted_DEK
   )
   # KMS verify IAM permissions của caller
   # KMS unwrap DEK inside KMS infrastructure
   # KMS trả về plaintext DEK

3. Decrypt data với DEK (locally, không cần network call):
   plaintext_data = AES-256-GCM.Decrypt(key=DEK_plaintext, ciphertext=ciphertext_data)

4. Xóa DEK khỏi memory sau khi dùng xong (best practice)

Security boundary rõ ràng: Tại bước 2, nếu caller không có IAM permission roles/cloudkms.cryptoKeyDecrypter, KMS trả về PERMISSION_DENIED — DEK không được unwrap — data không thể decrypt được, dù caller đang giữ encrypted_DEK trong tay.


Google's internal key hierarchy — ba tầng

Để hiểu đầy đủ CMEK, cần biết Google tự quản lý encryption của infrastructure ra sao. Google dùng ba tầng key hierarchy:

                    ┌──────────────────────────────────────────┐
Tầng 1              │      Keystore Master Key (KMS Root)      │
(Root of Trust)     │  - Stored trong Keystore (Google's KMS)  │
                    │  - Rotate theo schedule 90 ngày           │
                    │  - Hardware protected                     │
                    └────────────────┬─────────────────────────┘
                                     │ wrap
                    ┌────────────────▼─────────────────────────┐
Tầng 2              │      KMS Master Key (per-location)        │
(Service KMS)       │  - Một key per GCP location              │
                    │  - Được wrap bởi Keystore master key     │
                    │  - Cloud KMS servers fetch on startup     │
                    │  - Refreshed daily                        │
                    └────────────────┬─────────────────────────┘
                                     │ wrap (khi dùng Google-managed keys)
                                     │ hoặc
                                     │ ← customer KEK (khi dùng CMEK)
                    ┌────────────────▼─────────────────────────┐
Tầng 3              │       KEK (Key Encryption Key)            │
(Customer Layer)    │  - Google-managed HOẶC CMEK              │
                    │  - Wrap DEKs của từng service             │
                    └────────────────┬─────────────────────────┘
                                     │ wrap
                    ┌────────────────▼─────────────────────────┐
Tầng 4              │       DEK (Data Encryption Key)           │
(Data Layer)        │  - Unique per object/operation            │
                    │  - AES-256-GCM                            │
                    │  - Encrypts actual data at rest           │
                    └──────────────────────────────────────────┘

CMEK thay thế Tầng 3: Khi bạn bật CMEK cho Cloud Storage bucket, thay vì Google tự tạo và quản lý KEK, bạn cung cấp KEK từ Cloud KMS. DEKs cho objects trong bucket đó sẽ được wrap bằng KEK của bạn thay vì Google-managed KEK.


CMEK — Customer-Managed Encryption Keys

Sự khác biệt thực sự giữa CMEK và Google-managed encryption

Theo mặc định (Google-managed encryption):

  • Google tạo và quản lý KEK
  • Bạn không thể xem, rotate, hoặc revoke KEK
  • Không có audit trail cho KEK usage
  • Google có operational access đến KEK (để maintain system)

Với CMEK:

  • Bạn tạo và quản lý KEK trong Cloud KMS
  • Bạn có thể xem key metadata (nhưng không phải key material)
  • Bạn có thể rotate KEK theo schedule của mình
  • Bạn có thể revoke access bằng cách disable key hoặc remove IAM binding → GCP services không thể decrypt data
  • Cloud Audit Logs ghi lại mọi Encrypt/Decrypt call đến key của bạn

"Revoke access bằng cách disable key" là capability rất powerful — và rất nguy hiểm. Một số services (ví dụ: Cloud Spanner) sẽ tự động xóa database sau 30 ngày nếu key không accessible. Đây là HYOK (Hold Your Own Key) use case: trong tình huống data exfiltration hoặc compliance emergency, bạn có thể "brick" data bằng cách disable key.

IAM binding cho CMEK

Khi enable CMEK cho một GCP service, service agent (not your application SA) cần quyền dùng key:

bash
# Ví dụ: bật CMEK cho Cloud Storage bucket
# Service agent của Cloud Storage = service-PROJECT_NUMBER@gs-project-accounts.iam.gserviceaccount.com

gcloud kms keys add-iam-policy-binding my-kek \
  --location=us-central1 \
  --keyring=prod-keys \
  --member="serviceAccount:service-PROJECT_NUMBER@gs-project-accounts.iam.gserviceaccount.com" \
  --role="roles/cloudkms.cryptoKeyEncrypterDecrypter"

Điều quan trọng: Service agent khác với service account của application. Người dùng/application không cần quyền trên KMS key — chỉ service agent cần. Application có thể write/read GCS objects mà không cần thấy key.

Điều này tạo ra clean separation: IAM cho data access (ai được đọc GCS bucket) là tách biệt hoàn toàn với IAM cho key access (ai được dùng encryption key). Một engineer có thể có quyền đọc GCS objects mà không có quyền disable encryption key, và ngược lại.

Services hỗ trợ CMEK

Hầu hết GCP services major đều hỗ trợ CMEK:

  • Cloud Storage (CMEK trên bucket level)
  • BigQuery (dataset level và table level)
  • Cloud SQL (instance level)
  • GKE (node boot disk, etcd encryption, Secret encryption)
  • Pub/Sub (subscription level)
  • Artifact Registry
  • Cloud Run (và Cloud Functions)
  • Dataflow, Dataproc, Bigtable, Firestore...

CMEK không bảo vệ mọi thứ

CMEK bảo vệ data at rest. Nó không bảo vệ:

  • Data trong memory của Google's infrastructure khi đang xử lý
  • Data trong transit giữa services (được bảo vệ bởi TLS, tách biệt)
  • Metadata về resources (tên bucket, labels, etc.)
  • Backup data trừ khi backup cũng được configure với CMEK

Envelope encryption trong Secret Manager

Secret Manager cũng dùng envelope encryption với CMEK:

Secret payload

      ▼ mã hoá bởi
DEK (ngẫu nhiên per secret version)

      ▼ wrapped bởi
KEK (Cloud KMS key của bạn nếu dùng CMEK,
     hoặc Google-managed key nếu default)

      ▼ stored trong
Google's distributed storage infrastructure

Khi bạn call AccessSecretVersion():

  1. Secret Manager fetch encrypted_DEK từ storage
  2. Secret Manager gọi Cloud KMS Decrypt() để unwrap DEK (check IAM của Secret Manager service agent trên your KMS key)
  3. Secret Manager dùng DEK để decrypt payload
  4. Payload được return đến caller (check IAM của caller trên Secret Manager secret)

Hệ quả: Nếu bạn disable CMEK key, Secret Manager không thể decrypt bất kỳ secret version nào sử dụng key đó. Ngay cả admin của Secret Manager cũng không thể access data.


Common mistakes với CMEK

Nhầm CMEK với access control

CMEK không phải access control — nó là encryption key management. IAM vẫn là cơ chế kiểm soát ai được access data. CMEK bổ sung một lớp: ngay cả khi IAM grants quyền, nếu KEK bị disabled, không ai access được.

Delete key mà quên re-encrypt

Khi rotate KEK và destroy version cũ, nếu còn DEKs được wrapped bằng version cũ mà chưa được re-wrapped với version mới, data tương ứng mất vĩnh viễn. Cloud KMS cung cấp Re-encrypt data workflow để handle này, nhưng cần được thực hiện trước khi destroy old key version.

CMEK cross-region mismatch

KEK phải ở cùng region với data nó mã hoá (hoặc một superset). Ví dụ: không thể dùng key ở us-central1 để mã hoá Cloud Storage bucket ở europe-west1. Violation này sẽ bị reject khi configure CMEK.


References