Skip to main content
A Cloud KMS signer uses a signing key generated and stored inside a cloud key management service — AWS KMS, Azure Key Vault, or GCP Cloud HSM. The key is non-extractable by design: no employee at your company (or at the cloud provider) can ever retrieve the raw key material. Cloud KMS signers support advanced enterprise security controls natively, including IP allowlisting, cloud IAM-based access policies, rate limiting, circuit breakers, and detailed audit logs and alerting. For a conceptual overview, see Cloud KMS in the Wallet Signers guide. To learn how to register additional operational signers on an existing wallet, see Registering a signer.

How It Works

  1. You create a signing key inside Google Cloud KMS — the private key never leaves Google’s hardware.
  2. A Cloud Run function sits in front of KMS and signs transaction digests on demand.
  3. The Crossmint SDK calls your Cloud Run function whenever the wallet needs to sign something.
  4. The signature is converted from Google’s format to Ethereum’s format, and the Crossmint SDK uses it to complete the transaction.
That is it — your key stays in the HSM, and Crossmint never sees it.

What You Will Build

  • An asymmetric signing key in Google Cloud KMS (secp256k1)
  • A Cloud Run function that signs digests via KMS
  • A Crossmint server wallet using your KMS key as its signer

Prerequisites


Set Up Google Cloud KMS

1

Enable the Cloud KMS API

Navigate to Cloud Key Management in the Google Cloud Marketplace and click Enable.
2

Create a Key Ring

Go to Security > Key Management in the Google Cloud Console and click Create Key Ring.Create a key ring
  • Key ring name: crossmint-keys (or your preferred name)
  • Location: Select a region, e.g. us-west1
3

Create an Asymmetric Signing Key

Inside your key ring, click Create Key with the following settings:Create a key
You must use the secp256k1 curve for EVM-compatible wallets. Other curves (e.g. P-256) will not produce valid Ethereum signatures.
4

Download the Public Key

Once the key is created, click on the key version, select Get Public Key, and download it in PEM format.Download the public keySave the contents — you will need this PEM string in later steps. It looks like:

Set Up IAM Permissions

1

Create a Service Account

Navigate to IAM & Admin > Service Accounts and create a new service account (e.g. kms-signer-sa).
2

Grant KMS Permissions

Assign the following role to the service account:
  • Role: Cloud KMS CryptoKey Signer/Verifier (roles/cloudkms.signerVerifier)
This follows the principle of least privilege — the service account can only sign and verify, not manage or destroy keys.

Deploy a Cloud Run Signing Function

This function receives a digest, signs it with your KMS key, and returns the DER-encoded signature.
1

Create a Cloud Run Function

Go to Cloud Run Functions and create a new function:
  • Name: kms-signer-function
  • Region: Same region as your key ring (e.g. us-west1)
  • Runtime: Node.js 18+
  • Authentication: Configure based on your security requirements
For production, restrict access to your Cloud Run function using IAM authentication or VPC Service Controls. Allowing unauthenticated access is only suitable for development.
2

Set Environment Variables

In the Cloud Run function settings, go to the Containers tab, expand Edit Container, then select the Variables & Secrets tab. Add the following environment variables. To get these values, use Copy resource name from the same key version actions menu where you downloaded the public key — it gives you a path like projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY_NAME/cryptoKeyVersions/VERSION.Add environment variables to container
3

Add the Function Code

Set the Function entry point to signDigest, then paste the following code:
index.js
Add @google-cloud/kms to your function’s package.json dependencies:Add the google kms dependency
4

Deploy and Test

Deploy the function and note the URL — you will need it in the next step.Test with a sample request:
You should receive a JSON response containing a derSignature field.

Create and Use the Crossmint Wallet

Now wire everything together — convert your KMS public key to an Ethereum address, create a Crossmint wallet, and sign transactions through your Cloud Run function.

Install Dependencies

Convert the KMS Public Key to an Ethereum Address

Google Cloud KMS returns public keys in PEM/DER format. This helper extracts the raw public key bytes and converts them to an Ethereum address using viem.
kms-utils.ts

Build the KMS Signing Function

Cloud KMS returns DER-encoded signatures. Ethereum requires r, s, v format with EIP-2 low-s normalization. This function handles the full conversion:
kms-signer.ts

Create the Wallet

Use the KMS-derived Ethereum address as the wallet’s recovery signer. The recovery signer is used for wallet recovery and adding new signers — ideal for a server-held KMS key.
create-wallet.ts

Use the Wallet

Once created, retrieve the wallet and use it to sign transactions. Here are a couple of examples:
use-wallet.ts

Security Best Practices

Key rotation caveat: While Cloud KMS supports automatic key rotation, rotating an asymmetric signing key generates a new key pair — which means a new Ethereum address. For wallets, manage key versions carefully and plan migrations accordingly.
  • Restrict Cloud Run access: Use IAM authentication or VPC Service Controls to ensure only authorized services can call your signing function.
  • Enable audit logs: Turn on Cloud KMS “Data Access” audit logs to track every signing operation.
  • Principle of least privilege: Only grant the signerVerifier role — never grant admin or encrypterDecrypter roles to your signing service account.
  • Environment variables: Never hardcode your Crossmint API key or GCP credentials. Use environment variables or a secrets manager.