← Knowledge Center Native-SDK conformance · case study

Running GCP KMS & Secret Manager locally with the native SDK: gRPC vs HTTPS

Google's client libraries are excellent — and by default they talk gRPC. For most services that's invisible. But for Cloud KMS and Secret Manager, two things line up that make local development hard: the default transport is gRPC, and Google ships no emulator for either (unlike Pub/Sub or Firestore). This is how we kept the native google-cloud-kms / google-cloud-secretmanager SDKs working as-is against a local appliance by using a transport they already support — HTTPS — and what that costs.

1. The wall — gRPC

The native google-cloud-kms and google-cloud-secretmanager SDKs default to gRPC against *.googleapis.com. Serving gRPC ourselves means standing up HTTP/2 with protobuf framing, trailers, and a faithful re-implementation of each service's exact .proto contract — a heavy build for what is, here, two services. And unlike Pub/Sub and Firestore, Google publishes no local emulator for KMS or Secret Manager, so there's nothing official to lean on.

So the naive options are both bad: re-implement gRPC service-by-service, or fake it and return a green that the real SDK would never have produced.

2. The tech choice — build around HTTPS

The key insight: these are the same SDKs, and they already expose a REST (HTTPS) transport. Google's gax layer ships an HttpJson channel; the client settings expose a newHttpJsonBuilder(). Point that at the appliance's HTTPS endpoint with NoCredentials, and the unmodified native client does real encrypt/decrypt and secret access over plain HTTPS — backed by a Vault-transit engine the SDK never sees.

// Native google-cloud-kms — same client classes & calls as production.
// One transport line changed: REST (HttpJson) instead of the default gRPC.
KeyManagementServiceSettings settings =
    KeyManagementServiceSettings.newHttpJsonBuilder()
        .setEndpoint(System.getenv("GCP_REST_ENDPOINT"))        // appliance HTTPS (caddy), host:port
        .setCredentialsProvider(NoCredentialsProvider.create()) // appliance ignores auth
        .build();

try (KeyManagementServiceClient client = KeyManagementServiceClient.create(settings)) {
    CryptoKeyName keyName = CryptoKeyName.of(project, location, "my-ring", "my-key");

    EncryptResponse enc = client.encrypt(keyName, ByteString.copyFromUtf8("top-secret"));
    DecryptResponse dec = client.decrypt(keyName, enc.getCiphertext());

    assert dec.getPlaintext().toStringUtf8().equals("top-secret"); // real round-trip
}

Secret Manager is the identical pattern — SecretManagerServiceSettings.newHttpJsonBuilder() — for createSecret → addSecretVersion → accessSecretVersion → deleteSecret. This is exactly the spirit of AWS's endpointOverride: still the native SDK, just configured to a transport and endpoint it natively supports.

3. The trade-off, stated plainly

Driving the REST channel instead of gRPC has real, concrete implications — and they're all about transport, not about your business logic:

  • gax builds HTTPS URLs, so you target the appliance's caddy host:port, and the cert must be trusted by the JVM (add it to your truststore — same as any private TLS endpoint). gRPC-to-an-http://-endpoint won't work here; the REST channel is HTTPS.
  • No channel pooling. The HttpJson transport doesn't multiplex like gRPC; for local dev and CI that's a non-issue.
  • protojson encoding. Request/response must match Google's canonical protojson mapping — which the SDK and the appliance both honour, so it's transparent to you.
  • What you give up vs gRPC: bidirectional streaming and some deadline/retry nuances — none of which apply to KMS encrypt/decrypt or secret access.

4. SDK conformance

The snippet is the whole guarantee: same client classes, same method calls as the code you deploy to GCP. Exactly one line changes the transport (newHttpJsonBuilder() and an endpoint). There's no Vyomi SDK and no wrapper; the Vault-transit backing behind KMS is invisible and swappable. Drop the HttpJson settings and point the default client at real GCP, and the identical encrypt/decrypt code runs against the cloud.

5. What is guaranteed (KMS / Secrets)

  • Guaranteed: the official google-cloud-kms / google-cloud-secretmanager SDKs, unmodified, config-only (REST transport + endpoint); a real encrypt → decrypt round-trip and secret create → access → delete; portable code; backing tech (Vault) invisible and swappable.
  • Not guaranteed (said out loud): gRPC-specific transport behaviours (streaming, channel multiplexing, some deadline semantics); cloud-scale latency, quotas, and billing. You also supply the JVM trust for the local TLS cert — a one-time setup, not a code change.

Part of the Vyomi Knowledge Center series on native-SDK conformance. Companion: “AMQP vs HTTPS” — Azure messaging. Verified on a live appliance (2026-06-22): native google-cloud-kms / secretmanager over HttpJson, encrypt→decrypt and secret round-trips green (11/12 overall).