Skip to content
Open
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
29 changes: 25 additions & 4 deletions docs/production-deployment/temporal-proxy/encrypt-payloads.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ import { ReleaseNoteHeader } from '@site/src/components';

The proxy can encrypt Workflow and Activity payloads on the hop to an upstream and decrypt them on responses, set under
the top-level `encryption` block. It is off by default. Workers and Clients keep exchanging cleartext with the gateway;
the proxy seals payloads before they leave and opens them on the way back, so the upstream Temporal Service only ever
stores ciphertext. Encryption is transparent, requiring no change to Worker or Client code.
the proxy seals codec-capable Payloads before they leave and opens them on the way back. New Payloads sent through the
proxy reach the upstream Temporal Service as ciphertext. Encryption is transparent, requiring no change to Worker or
Client code.

It uses envelope encryption: a short-lived data encryption key (DEK) encrypts each payload with AES-256-GCM, and a KMS
key you own wraps the DEK. The wrapped DEK and a reference to the key that wrapped it travel with the payload, so the
Expand All @@ -45,8 +46,8 @@ flowchart LR

App -->|cleartext request| Seal
Seal -->|wrap DEK| KMS
Seal -->|ciphertext| Upstream
Upstream -->|ciphertext response| Open
Seal -->|Payloads: ciphertext<br/>other fields: cleartext| Upstream
Upstream -->|Payloads: ciphertext<br/>other fields: cleartext| Open
KMS -->|unwrap DEK| Open
Open -->|cleartext response| App
```
Expand Down Expand Up @@ -77,6 +78,26 @@ encryption:
- `cacheSize` bounds the in-memory cache of decrypted DEKs, which avoids a KMS call on every message. It must be
non-negative.

:::note Scope of fail-closed behavior

Fail-closed applies to outbound codec-capable Payloads on calls that pass through a proxy where `encryption.enabled` is
`true`. If the proxy cannot encrypt one of these Payloads, such as when the KMS is unavailable, it fails the request
before sending it upstream. It does not fall back to plaintext.

The proxy cannot enforce encryption for a Client, Worker, Web UI, or CLI that connects directly to the upstream Temporal
Service. Restrict credentials and network paths when all application traffic must pass through the proxy.

On responses, the proxy decrypts Payloads that carry its encryption metadata. It passes other Payloads through unchanged
so data written before proxy adoption remains readable during a migration. This behavior continues until existing
plaintext data ages out under the Namespace's retention period.

Fail-closed does not mean that every request field is encrypted. Search Attributes remain unencrypted so the Temporal
Service can index them. Failure messages and call stacks are not codec-capable Payloads by default. See
Comment thread
Duncanma marked this conversation as resolved.
[Codecs and Encryption](/production-deployment/data-encryption) for encryption coverage and
[Failure Converter](/failure-converter) for failure encoding.

:::

`default` and each `overrides` entry are key policies with the same shape:

| Field | Meaning |
Expand Down
6 changes: 4 additions & 2 deletions docs/production-deployment/temporal-proxy/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,10 @@ For each request, the gateway:

The per-upstream proxy then rewrites the local Namespace to the name the upstream expects, attaches that upstream's TLS
and credentials, forwards to the Temporal Service, and translates the Namespace back on responses. When payload
encryption is enabled, it also seals payloads on the way out and opens them on the way back, so the upstream only ever
stores ciphertext.
encryption is enabled, it also seals codec-capable Payloads on the way out and opens them on the way back. New Payloads
sent through the proxy reach the upstream as ciphertext. See
[Encrypt payloads](/production-deployment/temporal-proxy/encrypt-payloads) for the scope and limits of this fail-closed
behavior.

### Terms

Expand Down