Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
[![license](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

A gRPC proxy that sits between Temporal SDK Clients, Workers, and the Temporal UI on one side and one or more upstream
Temporal Services on the other. It handles Namespace translation and TLS termination so applications can target a single
local endpoint while the proxy fans requests out to the right upstream (a local dev Temporal Service, a self-hosted
deployment, Temporal Cloud, or some mix).
Temporal Services on the other. It handles Namespace translation, TLS termination, and payload encryption so
applications can target a single local endpoint while the proxy fans requests out to the right upstream (a local dev
Temporal Service, a self-hosted deployment, Temporal Cloud, or some mix).

> [!NOTE]
>
Expand Down Expand Up @@ -61,6 +61,9 @@ flowchart LR
overrides) in both requests and responses.
- **TLS termination and outbound credentials.** Terminate inbound TLS/mTLS and attach the upstream's own TLS and
credentials (API key or mTLS), so client code carries none of it.
- **Payload encryption.** Optionally seal payloads with envelope encryption on the hop to an upstream and open them on
responses, so the upstream only ever sees ciphertext while local Workers keep exchanging cleartext. DEKs are wrapped
by a KMS key (AWS KMS, Azure Key Vault, or GCP KMS), rotate automatically, and can be overridden per Namespace.
- **Inbound authentication.** Optional static-token or JWKS validation on the gateway; off by default.
- **Codec-transparent.** The gateway never parses payloads. It peeks the Namespace, picks an upstream, and relays raw
frames in both directions.
Expand Down
11 changes: 11 additions & 0 deletions examples/cloud/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,14 @@ namespace name `quickstart`. For each request the proxy:
> [!NOTE]
>
> With a single namespace both upstreams resolve to the same host; the split is what lets the same config scale to many.

## Optional: encrypt payloads to Cloud

`config.yaml` ends with a commented-out `encryption:` block. Uncomment it and restart the proxy to encrypt workflow and
activity payloads on the hop to Cloud: the worker and starter keep exchanging cleartext, the proxy seals payloads before
they leave and opens them on the way back, and Cloud only ever stores ciphertext (workflow inputs and results show as
encrypted bytes in the Cloud UI).

The block uses a `testing://` key, which holds its key material in the config itself with no cloud KMS. That is fine for
this toy but never for real data; in production point the key at `awskms://`, `azurekeyvault://`, or `gcpkms://`
instead.
19 changes: 19 additions & 0 deletions examples/cloud/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,22 @@ upstreams:
credentials:
static:
apiKey: ${TEMPORAL_API_KEY}

# Optional: encrypt payloads on the hop to Cloud. Uncomment to seal workflow and
# activity payloads before they leave the proxy and open them on the way back;
# the worker and starter keep exchanging cleartext, and Cloud only ever stores
# ciphertext (workflow inputs and results show as encrypted bytes in the Cloud
# UI). Restart the proxy after changing this.
#
# The key below is a throwaway local test key: the "testing://" scheme holds the
# key material in the config itself with no cloud KMS, which is fine for a toy but
# never for real data. In production, point uri at a KMS key instead (awskms://,
# azurekeyvault://, or gcpkms://).
#
# encryption:
# enabled: true
# cacheSize: 200
# default:
# uri: testing://KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKio=
# duration: 1h
# renewBefore: 15m