---
title: "Read payloads in Temporal UI"
description: "Point Temporal's UI at the edge's codec when you need to inspect encrypted payloads."
canonical_url: "https://docs.oz0.ai/fleet/temporal-backends/codec"
---
# Read payloads in Temporal UI

> Point Temporal's UI at the edge's codec when you need to inspect encrypted payloads.

For: cluster operators.

Point Temporal's UI at the edge's codec when you need to inspect encrypted payloads.

## Temporal's UIs: the codec endpoint

Temporal's UI shows ciphertext until it is given a codec server. The edge serves one at `https://<edge>:7443/codec`.

Temporal Cloud UI. In the namespace's settings, under *Codec Server*:

1. Endpoint: `https://<edge address>:7443/codec`. It must be reachable from your browser, not from the internet, and
its certificate must be one your browser trusts: put the edge behind a load balancer with your own certificate, or
add its address with `--san`.
2. Turn on Pass the user access token. Leave *Include cross-origin credentials* off: the edge never reads cookies.
3. Link each person's Temporal Cloud email to their account: `oz0 user link-temporal-cloud kim kim@example.com`.

The edge checks the access token's signature against Temporal Cloud's keys, finds the account linked to its email, and
decodes only for accounts with the [content permission](https://docs.oz0.ai/concepts/security) on the tenant. Encoding (when the UI sends
a signal) also needs the operator role. Every decode and encode is in the audit log as `payload.decode` or
`payload.encode`, and every refusal of a signed-in person as `payload.decode.refused` or `payload.encode.refused`;
requests without a valid token are only logged. Only `https://cloud.temporal.io` may call it from a browser; add other
origins with `--codec-allow-origin`.

The Temporal Cloud UI sends the same access token to the codec server of every namespace a person browses, including
other organizations' namespaces, whose codec servers could send it on to your edge. So the edge takes access tokens
only when they are bound to your cluster.

With Temporal Cloud's keys the binding is `--codec-account-claim`: the
name of a claim that must hold your `--temporal-cloud-account`. An audience binds only when it names your cluster
alone, and a token for any Temporal Cloud account can carry the same one, so with Temporal Cloud's keys
`--codec-jwt-audience` is checked when set but does not count as a binding.

With an identity provider's own keys
(`--codec-jwks-url`), an audience that provider issues for your codec endpoint alone binds them.

Until the tokens are
bound, the edge takes none (operators' certificates and tenant API keys still decode), says so at start, and the
encryption status shows the codec endpoint as closed.

Which claims Temporal Cloud's tokens carry is not documented
yet, so check one of your tokens for a claim that names your account before you set it.

`--codec-jwt-unbound` takes
any unexpired token of a linked user that nothing binds, as earlier versions did, knowing that another codec server
could replay one here; the edge warns at start.

Either way, a token is taken for at most `--codec-jwt-max-age`
(default 12 hours) after it was issued.

A token's address must be verified: its `email_verified` claim must say `true` (the JSON boolean, or the string
`"true"` some providers send, as at [sign-in](https://docs.oz0.ai/admin/sign-in)); any other value is refused. Temporal Cloud's own
tokens name the Temporal Cloud user by the address they were invited with and are not documented to carry the
claim, so with Temporal Cloud's keys a token without it is taken.

With an identity provider's own keys, a token
without the claim is refused unless you set `--codec-assume-email-verified`, for a provider that verifies or sets
every address itself (such as Microsoft Entra ID, as sign-in's `--assume-email-verified`).

Temporal's own UI and CLI against an external cluster. The Temporal CLI decodes with a tenant API key (one of the
whole tenant: a key [scoped](https://docs.oz0.ai/build/apps/runtime-api/authentication#keys-scoped-to-agents-and-flows) to some agents is refused, since the
codec decodes any job's payloads):

```bash
temporal workflow show --workflow-id job-123 --namespace default \
  --codec-endpoint https://edge.internal:7443/codec --codec-auth "Bearer $OZ0_API_KEY"
```

For a self-hosted Temporal UI against an external cluster (its own deployment, not the one the console embeds), set its
codec endpoint to the edge, `TEMPORAL_CODEC_ENDPOINT=https://<edge>:7443/codec` with
`TEMPORAL_CODEC_PASS_ACCESS_TOKEN=true`, and point `--codec-jwks-url`, `--codec-jwt-issuer` (required with
`--codec-jwks-url`), `--codec-email-claim` and `--codec-jwt-audience` (an audience the provider issues for this
codec endpoint alone) at the identity provider whose tokens it passes, with `--codec-assume-email-verified` if its
tokens carry no `email_verified` claim.
Without a codec endpoint that UI shows ciphertext, which, now that a cluster encrypts by default, is what it shows for
every job.

The console. On Temporal Cloud the embedded Temporal UI is not served (`/temporal/` says why); each job's page links
to its workflow in the Temporal Cloud UI instead, and the overview shows the backend. With an embedded or external
backend, the embedded Temporal UI at `/temporal/` decodes payloads with its own codec on the management port, for the
admin signed in: see [Temporal's UI](https://docs.oz0.ai/fleet/separate-roles/temporal-ui#temporals-ui).


## Sitemap

See the full [sitemap](https://docs.oz0.ai/sitemap.md) for all pages.
