Nonceworks

Google Cloud KMS signer: a service-account key, not workload identity

Written 10 October 2026

Applies to OpenZeppelin Relayer 1.8.0 and current main as of October 2026, read from the source. Upstream: openzeppelin-relayer #757 asks for GKE workload identity and is open.

What the signer reads

The google_cloud_kms signer takes a service_account object and a key object, and its config rejects unknown fields (src/models/signer/config.rs):

  • service_account: project_id, private_key_id, private_key, client_email and client_id, plus auth_uri, token_uri, the certificate URLs and universe_domain (default googleapis.com), which have defaults. private_key_id, private_key and client_email can be environment references ({"type": "env", "value": "..."}); project_id and client_id are plain strings.
  • key: location (default global), key_ring_id, key_id and key_version (default 1).

These are the fields of a service-account key file, minus type. Because the config rejects unknown fields, a key file pasted in as it is fails to load.

What it does not read

The signer has no path for Application Default Credentials: no GOOGLE_APPLICATION_CREDENTIALS, no metadata server, no GKE workload identity or workload identity federation. On GKE the signer still needs a service-account key. Two other parts of the same release do have such a path: the Pub/Sub queue backend authenticates with Application Default Credentials, and the Azure Key Vault signer has a workload identity option that takes a federated token file, by default from AZURE_FEDERATED_TOKEN_FILE.

What to do on 1.8.0

  • Keep the key out of the image and out of config.json: give private_key_id, private_key and client_email as environment references, filled from a Kubernetes Secret or your secret manager. That is still a long-lived key, so give the service account nothing but the one KMS key, and rotate it.
  • Grant Cloud KMS CryptoKey Signer and Cloud KMS CryptoKey Public Key Viewer on that key, or Cloud KMS CryptoKey Signer/Verifier alone. Cloud KMS Viewer does not include viewPublicKey, which the signer needs to derive its address (#914).
  • To revoke, remove the role binding or disable the service account; Google says role changes can take seven minutes or more to take effect. The security page covers what the grant allows.

We have not run this signer against a real Google Cloud key yet, so a move to it starts with your key on a testnet.