Data in Google Cloud is encrypted at rest by default with Google-managed keys. Two services cover what is left: Secret Manager for application secrets and Cloud KMS for keys you manage yourself.
flowchart LR APP["Cloud Run service<br/>runs as web-sa"] -- "secretAccessor" --> SM["Secret Manager<br/>db-password version 3"] APP --> SQL["Cloud SQL"] KMS["Cloud KMS key ring<br/>key app-data"] -- "CMEK" --> GCS["Bucket and disks"] AG["Service agent"] -- "Encrypter/Decrypter" --> KMS %% step APP: The service runs as web-sa, which holds roles/secretmanager.secretAccessor on one secret only. %% step SM: The app reads db-password, version latest or a pinned version, at start-up or as a mounted file. %% step SQL: With the password it connects to Cloud SQL; no secret is stored in the image or Git. %% step KMS: A key ring in a region holds the key app-data; the key rotates automatically. %% step AG: The storage service agent is granted Encrypter/Decrypter on the key so it can use CMEK. %% step GCS: Objects and disks are encrypted with your key; disabling the key makes the data unreadable.
Secret Manager
- A secret has versions; each version is an immutable value. Refer to
latestor to a fixed version number. - Replication:
automatic(Google chooses) or user-managed regions for residency rules. - Access with
roles/secretmanager.secretAccessoron one secret, not on the project. - Cloud Run and GKE can expose a secret as an environment variable or a mounted file; a mounted
latestupdates without redeploying. - Rotation schedules publish a message to Pub/Sub so your code can create a new version.
- Disable or destroy old versions after rotation.
printf 'S3cr3t!' | gcloud secrets create db-password --replication-policy=automatic --data-file=-
gcloud secrets versions access latest --secret=db-password
gcloud secrets add-iam-policy-binding db-password --member=serviceAccount:web-sa@dl-lab-dev.iam.gserviceaccount.com --role=roles/secretmanager.secretAccessor
Cloud KMS
| Object | Notes |
|---|---|
| Key ring | Regional or multi-regional container; cannot be deleted |
| Key | Has a purpose (encryption, signing) and a rotation period, e.g. 90 days |
| Key version | The actual key material; destroying a version is scheduled (30 days by default) |
| Protection level | Software, HSM (Cloud HSM) or external (Cloud EKM) |
CMEK (customer-managed encryption keys): services such as Cloud Storage, Persistent Disk, BigQuery and Cloud SQL encrypt data with your KMS key. Grant the service’s service agent roles/cloudkms.cryptoKeyEncrypterDecrypter on the key, and keep the key in the same location as the data.
| Command | Meaning |
|---|---|
gcloud kms keyrings create app-ring --location=asia-southeast1 |
Key ring |
gcloud kms keys create app-data --keyring=app-ring --location=asia-southeast1 --purpose=encryption --rotation-period=90d --next-rotation-time=… |
Key with rotation |
gcloud secrets versions list db-password |
Secret versions |
Traps: Secret Manager is for secrets, not large files (64 KiB per version); environment-variable secrets are read at start-up only; destroying a KMS key version makes data encrypted with it unrecoverable.