Skip to main content

Encryption & CMEK

Exam guide§3.2

Data in Google Cloud is always encrypted at rest by default - the exam question is only about who controls the keys.

  • Google-managed keys (default) - Google creates, rotates, and stores the keys. Zero config, zero effort. This is the default for every service.
  • CMEK - Customer-Managed Encryption Keys - you create and manage the key in Cloud KMS. Google still uses it to encrypt/decrypt, but you control rotation, and can disable or destroy the key (which makes the data unrecoverable). Pick when the question says "control our own keys", "compliance requires key rotation control", or "ability to revoke access by destroying keys".
  • CSEK - Customer-Supplied Encryption Keys - you supply your OWN raw key material with each request; Google never stores it. Most control, most burden. Limited to Cloud Storage and Compute Engine. Pick when the org insists Google must never hold the key at all.
DECISIONWhich key management?
No special requirementGoogle-managed (default)
Control rotation, disable/revoke keys, audit key useCMEK (Cloud KMS)
Google must never store the key materialCSEK
Hardware-backed / FIPS keysCloud KMS with Cloud HSM
Pick this when: default unless a policy demands more control
GotchaDestroying a CMEK key destroys the data

With CMEK, if you disable or destroy the key in Cloud KMS, the data encrypted with it becomes permanently unreadable - even to Google. This "kill switch" is exactly why compliance questions favor CMEK, but it's also the operational risk. Google-managed keys have no such control.

NumbersCloud KMS essentials
  • Keys live in a key ring (regional grouping); grant use via the Cloud KMS CryptoKey Encrypter/Decrypter IAM role.
  • CMEK requires the service's service agent account to have that role on the key.
  • Automatic rotation is configurable (e.g. every 90 days) for symmetric keys.

CSEK with gsutil

Unlike CMEK, CSEK has no Cloud KMS integration - you carry the raw key yourself. For Cloud Storage that key lives in the .boto config file that gsutil reads. Generate the file once with gsutil config -n, then set the key fields. gsutil uses the single encryption_key to encrypt every upload and decrypt reads; the (up to 100) decryption_key entries only decrypt objects that were written under older keys.

~/.botoencryption_keyencrypts uploads · decrypts reads · ×1decryption_keydecrypt only · up to 100 keysBucketsetup.htmlkey A · encrypt + readsetup2.htmlkey B · read via decryption_keysetup3.htmlkey C absent → no decryption key matchesencrypt + readread
gsutil reads the .boto file: the single encryption_key encrypts new uploads and decrypts reads, while up to 100 decryption_key entries decrypt objects written under older keys. An object whose key sits in no slot cannot be read at all.

Rotating a key is just editing .boto: generate a new key, make it the new encryption_key, and move the old key down to a decryption_key so existing objects stay readable. To fully retire the old key you rewrite each affected object under the new key, then drop the old decryption_key.

GotchaNo decryption key matches

If you comment out or remove the key an object was encrypted with - and it isn't present as either the encryption_key or a decryption_key - the read fails with No decryption key matches object. The object isn't lost; you just need its key back in .boto. Because Google never stores CSEK keys, losing the key means losing the data.

CommandsSetting up CSEK in the .boto file
# 1. generate a 256-bit AES key (base64) - this is the key YOU keep
python3 -c 'import base64, os; print(base64.encodebytes(os.urandom(32)).decode())'
 
# 2. no ~/.boto yet? create one (the -n writes commented-out defaults)
ls -al ~/.boto || gsutil config -n
 
# 3. edit ~/.boto (nano ~/.boto, or the Cloud Shell editor) - under [GSUtil],
# uncomment and paste the key:
# encryption_key = <base64 AES-256 key> # encrypts uploads + decrypts reads
# decryption_key1 = <older base64 key> # decrypt-only, up to decryption_key100
 
# 4. uploads are now CSEK-encrypted; the console shows "customer-supplied key"
gsutil cp setup.html gs://my-bucket/
0%0 of 147 pages studied