Google Cloud KMS
Use Google Cloud KMS for MainSDK encryption keys - key rings per region, IAM roles, rotation, main.yaml, local testing and swapping.
Google Cloud KMS is one of the key services behind keys. MainSDK encrypts each record or file with its own data key and Cloud KMS wraps it with a key that never leaves Cloud KMS, one key per MainSDK region. Pick it when your app runs on Google Cloud.
Interfaces it serves
Pick Google Cloud KMS in main.yaml for any of these. Your calls stay the same, and you can swap later.
keysBuilding for 0.3Driver gcp-kms Google Cloud KMS
keys:
driver: gcp-kmsSwap to another provider
Before you start
- Enable the Cloud KMS API in your Google Cloud project.
- Create a key ring and a symmetric encryption key in a location for each MainSDK region (US, EU and India). Key rings belong to one location, so each region gets its own.
- Give your app an identity. Prefer the service account your compute runs as, or Workload Identity Federation outside Google Cloud. KMS credentials must come from workload identity or the
secretsdriver, never from code. - Grant only encrypt and decrypt on those keys, such as the Cloud KMS CryptoKey encrypter/decrypter role. Keep key administration with a separate identity.
Configure
keys:
driver: gcp-kms
key: # one wrapping key per region; [to be decided] confirm the identifier form the driver takes
us: projects/pinecart/locations/us-east1/keyRings/app/cryptoKeys/pinecart-us
eu: projects/pinecart/locations/europe-west1/keyRings/app/cryptoKeys/pinecart-eu
in: projects/pinecart/locations/asia-south1/keyRings/app/cryptoKeys/pinecart-in
per-user: true
rotate: 365dmainsdk check refuses the local driver in production with MAIN-KEYS-0001, so keep it in a development overlay.
Use it
import { keys } from "mainsdk";
export async function sealNote(note: string, user: { id: string }) {
return keys.encrypt(note, { owner: user, region: "in", label: "sensitive" });
// wrapped with the key under key.in
}db fields with encrypt: true and files use the same keys without any call from you.
Local development and testing
- No Google Cloud project: use the
localkeys driver in development. - Tests:
createTestApp()from@mainsdk/testingrunskeyson its in-memory fake, andchaos.on("keys", { outage: true })simulates Cloud KMS being unreachable. MainSDK's conformance suite runs thegcp-kmsdriver against an emulator or mock.
import { it } from "node:test";
import assert from "node:assert/strict";
import { createTestApp } from "@mainsdk/testing";
import { keys } from "mainsdk";
it("round-trips a sealed note", async () => {
createTestApp({ main: "./main.yaml" });
const sealed = await keys.encrypt("hello", { region: "eu", label: "personal" });
const plain = await keys.decrypt(sealed, { purpose: "test" });
assert.equal(new TextDecoder().decode(plain), "hello");
});What MainSDK adds on top
- A data key per record, wrapped by a Cloud KMS key that never leaves it.
- One wrapping key per region, chosen from the record owner's region.
- Every key use audited with key ID, purpose and caller, never the key material.
- Automatic rotation with old data still readable, and per-user keys for crypto-erasure.
See Encryption keys for the full contract.
Limits and notes
- The driver comes with the keys spec (phase 1), after the AWS KMS and Vault Transit drivers.
- Cloud KMS can rotate keys on its own schedule; how that interacts with MainSDK's
rotateperiod is not specified yet. - Google Cloud HSM and customer-held keys through Google External Key Manager come with the hsm-keys spec in phase 3.
keys.raw()returns the KMS client;mainsdk checklists every use.
Swap to or from it
keys:
driver: gcp-kms # was aws-kms; point key.us, key.eu and key.in at Cloud KMS keysFAQ
Can I use a multi-region location such as europe? MainSDK only asks for one key per MainSDK region; any Cloud KMS location that keeps the data where it must stay will do.
Does erasure reach backups? Yes, with per-user: true: the backup still holds ciphertext, but the key to open it is gone.
Next
Open questions
Was this page helpful?