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
60 changes: 60 additions & 0 deletions src/langsmith/kubernetes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,66 @@ LangSmith services listen on both IPv4 and IPv6 by default as of 0.14.0. No addi

You will also need to specify connection details for any external databases you are using.

### Configure a signing JWKS

Self-hosted LangSmith uses an Ed25519 JSON Web Key Set (JWKS) to sign tokens for its OAuth Authorization Server and LLM auth proxy. Configuring this key enables self-hosted OAuth login, including `langsmith auth login` and Remote MCP authentication, and allows LangSmith to sign requests sent through an LLM auth proxy.

The JWKS contains a private key. Store it in a Kubernetes Secret and keep it stable across upgrades. LangSmith derives the public key and serves it from `/.well-known/jwks.json`, so clients such as the LLM auth proxy can verify tokens without receiving the private key.

<Note>
The Helm configuration in this section requires LangSmith chart version 0.16.0 or later.
</Note>

Generate an Ed25519 key pair with [step CLI](https://smallstep.com/docs/step-cli/installation/) or your internal key-management process:

```shell
TMPDIR_KEYS="$(mktemp -d)"
step crypto keypair "$TMPDIR_KEYS/pub.pem" "$TMPDIR_KEYS/priv.pem" \
--kty OKP --crv Ed25519 --no-password --insecure
PRIV_JWK=$(step crypto key format --jwk --no-password --insecure < "$TMPDIR_KEYS/priv.pem")
SIGNING_JWKS=$(echo "$PRIV_JWK" | jq -c '{keys: [. + {use: "sig", alg: "EdDSA"}]}')
```

Choose one of the following storage options:

- **Chart-managed Secret**: Set `config.signingJwks` in your LangSmith `langsmith_config.yaml`. The chart stores the value in its managed Kubernetes Secret.

```yaml
config:
signingJwks: |
{"keys":[...]}
```

- **Existing Secret**: If your installation already uses `config.existingSecretName`, add the generated JWKS to that Secret under the exact key `langsmith_signing_jwks`:

```yaml
# Add this key to the existing chart-wide Kubernetes Secret.
stringData:
langsmith_signing_jwks: |
{"keys":[...]}
```

```yaml
config:
existingSecretName: "langsmith-secrets"
```

`config.existingSecretName` replaces the chart-managed Secret for the entire LangSmith installation. Do not point it to a JWKS-only Secret. Preserve all existing keys, including `langsmith_license_key` and `api_key_salt`. For the complete Secret structure, see [Use an existing Secret for your installation](/langsmith/self-host-using-an-existing-secret).

<Warning>
Starting with chart version 0.16.0, the chart owns `LANGSMITH_SIGNING_JWKS`. When upgrading from an earlier chart version, remove this environment variable from `commonEnv` and `platformBackend.deployment.extraEnv`. Setting it there causes a duplicate environment-variable error. Configure it through `config.signingJwks` or the `langsmith_signing_jwks` key in `config.existingSecretName` instead.
</Warning>

Apply the Helm release after configuring the JWKS. If you update an externally managed Secret without changing the Helm values, restart the platform-backend pods so they load the new environment variable.

Request the public JWKS from your LangSmith installation to verify the configuration:

```bash
curl https://<your-langsmith-host>/.well-known/jwks.json
```

The response contains the public verification key and does not include the private `d` field.

## Deploying to Kubernetes:

1. Verify that you can connect to your Kubernetes cluster(note: We highly suggest installing into an empty namespace)
Expand Down
2 changes: 1 addition & 1 deletion src/langsmith/langsmith-cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ Point the CLI at your instance with `--api-url`, or with `LANGSMITH_ENDPOINT`. B

<Tabs>
<Tab title="OAuth">
Requires LangSmith CLI `v0.2.46` or later and a deployment on LangSmith `0.16` or later, with the OAuth authorization server enabled. The chart exposes the OAuth authorization server under `/api`, but those endpoints stay inert until you configure a signing JWKS. For setup steps, see [Enabling Remote MCP](/langsmith/langsmith-remote-mcp#enabling-remote-mcp).
Requires LangSmith CLI `v0.2.46` or later and a deployment on LangSmith `0.16` or later, with the OAuth authorization server enabled. The chart exposes the OAuth authorization server under `/api`, but those endpoints stay inert until you [configure a signing JWKS](/langsmith/kubernetes#configure-a-signing-jwks).

The OAuth authorization server is enabled automatically when `config.hostname` is set in your Helm chart **and** a signing JWKS is configured (via `config.signingJwks`, or the key `langsmith_signing_jwks` in `config.existingSecretName`). Without the signing JWKS, the OAuth endpoints are inactive and the CLI will receive a `404` — use the API key tab instead.

Expand Down
25 changes: 5 additions & 20 deletions src/langsmith/langsmith-remote-mcp.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -189,27 +189,12 @@ If a client loses its session (for example, after revoking access in your LangSm

### Enabling Remote MCP

The Remote MCP and its OAuth Authorization Server are wired automatically when `config.hostname` is set, but they stay **inert (404)** until you provide a signing JWKS. This is the one piece of configuration LangSmith Cloud handles for you. To enable it:
The Remote MCP and its OAuth Authorization Server are wired automatically when `config.hostname` is set, but they stay **inert (404)** until you provide a signing JWKS. Follow [Configure a signing JWKS](/langsmith/kubernetes#configure-a-signing-jwks), then set the installation hostname in your LangSmith `values.yaml`:

1. **Generate an Ed25519 (OKP) JWKS.** RSA keys are rejected. For example, with [`step`](https://smallstep.com/docs/step-cli/):

```bash
step crypto jwk create /dev/null /tmp/jwk.json --kty OKP --crv Ed25519 --no-password --insecure -f
jq -c '{keys:[.]}' /tmp/jwk.json # wrap the single key in a JWKS
```

2. **Provide it to the chart** as `config.signingJwks` (stored in the chart secret), or as the key `langsmith_signing_jwks` in your [existing secret](/langsmith/self-host-using-an-existing-secret):

```yaml
config:
hostname: "your-langsmith-host"
signingJwks: |
{"keys":[ ... ]}
```

<Warning>
Do not set `LANGSMITH_SIGNING_JWKS` directly via `commonEnv` or `extraEnv`—the chart already wires it from the secret, and a manual copy fails the install with a duplicate environment-variable error. Use `config.signingJwks` or `config.existingSecretName` instead.
</Warning>
```yaml
config:
hostname: "your-langsmith-host"
```

After upgrading, the OAuth discovery endpoints and `/api/mcp` become live. Verify with:

Expand Down
34 changes: 5 additions & 29 deletions src/langsmith/llm-auth-proxy-self-hosted.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -58,40 +58,16 @@ Playground and Evals are available in v0.13.33+. Chat and Insights are available

Skip this step for LangSmith SaaS. JWT signing is already configured.

**Generate an Ed25519 key pair** using [step CLI](https://smallstep.com/docs/step-cli/installation/) (or an internal process if you prefer). Ed25519 is the signing algorithm LangSmith uses to sign JWTs. The private key signs each request; the auth proxy verifies the signature using only the public key.

```shell
TMPDIR_KEYS="$(mktemp -d)"
step crypto keypair "$TMPDIR_KEYS/pub.pem" "$TMPDIR_KEYS/priv.pem" \
--kty OKP --crv Ed25519 --no-password --insecure
PRIV_JWK=$(step crypto key format --jwk --no-password --insecure < "$TMPDIR_KEYS/priv.pem")
SIGNING_JWKS=$(echo "$PRIV_JWK" | jq -c '{keys: [. + {use: "sig", alg: "EdDSA"}]}')
echo "$SIGNING_JWKS"
```

**Store the JWKS in a Kubernetes secret:**

```shell
kubectl create secret generic langsmith-signing-jwks \
--namespace <namespace> \
--from-literal=LANGSMITH_SIGNING_JWKS="$SIGNING_JWKS"
```
Follow [Configure a signing JWKS](/langsmith/kubernetes#configure-a-signing-jwks) to generate the shared Ed25519 key and provide it to the LangSmith Helm chart. The private key signs each request, while the auth proxy fetches only the public key from LangSmith.

A JWKS (JSON Web Key Set) is a standard JSON format for publishing cryptographic keys. `LANGSMITH_SIGNING_JWKS` contains the Ed25519 private key and is stored as a Kubernetes secret. It is never exposed. LangSmith automatically extracts the corresponding public key and serves it at `/.well-known/jwks.json`. The auth proxy fetches this public endpoint to verify JWT signatures without ever needing the private key.

**Reference the secret in your [LangSmith `values.yaml`](https://github.com/langchain-ai/helm/blob/main/charts/langsmith/values.yaml):**
Set the issuer for LLM auth proxy tokens in your LangSmith `values.yaml`:

```yaml
platformBackend:
deployment:
extraEnv:
- name: LLM_AUTH_PROXY_ISSUER
value: "langsmith" # must match jwtIssuer in the auth proxy chart
- secretRef:
name: langsmith-signing-jwks
config:
llmAuthProxyIssuer: "langsmith"
```

`LLM_AUTH_PROXY_ISSUER` sets the `iss` claim in signed JWTs. Use `langsmith` to match the SaaS default, or a custom identifier like `langsmith:self-hosted:<short_identifier>` to distinguish your installation. The value must match `jwtIssuer` in the auth proxy chart in [Step 4](#4-install-the-auth-proxy-helm-chart)).
`config.llmAuthProxyIssuer` sets the `iss` claim in signed JWTs. Use `langsmith` to match the SaaS default, or a custom identifier like `langsmith:self-hosted:<short_identifier>` to distinguish your installation. The value must match `jwtIssuer` in the auth proxy chart in [Step 4](#4-install-the-auth-proxy-helm-chart).

## 2. Enable LLM Auth Proxy for your organization

Expand Down
2 changes: 1 addition & 1 deletion src/langsmith/profile-configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ For a self-hosted instance, pass its base URL. The CLI reads the deployment's au
```shell
langsmith auth login --api-url https://langsmith.example.com --profile self-hosted
```
Self-hosted OAuth login requires Helm chart `0.16.0` or later with a signing JWKS. For configuration, see [Enabling Remote MCP](/langsmith/langsmith-remote-mcp#enabling-remote-mcp). Otherwise create an API-key profile.
Self-hosted OAuth login requires Helm chart `0.16.0` or later with a signing JWKS. For setup steps, see [Configure a signing JWKS](/langsmith/kubernetes#configure-a-signing-jwks). Otherwise create an API-key profile.

For a headless environment, suppress automatic browser opening and pass a workspace ID:

Expand Down
6 changes: 3 additions & 3 deletions src/langsmith/self-host-using-an-existing-secret.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ stringData:
# Optional; include only while rotating engine_encryption_key. Accepted for
# decryption only, so runs encrypted just before the swap still complete.
engine_encryption_key_previous: foo
# Optional. Ed25519/OKP JWKS (JSON) that signs OAuth Authorization Server /
# Remote MCP tokens. Required only to enable the LangSmith Remote MCP server
# (see /langsmith/langsmith-remote-mcp); omit it otherwise.
# Optional. Ed25519/OKP JWKS (JSON) that signs OAuth Authorization Server and
# LLM auth proxy tokens. Required for self-hosted OAuth login, Remote MCP, and
# the LLM auth proxy (see /langsmith/kubernetes#configure-a-signing-jwks).
langsmith_signing_jwks: foo
# Required only when enabling LangSmith Sandboxes.
sandbox_x_service_auth_jwt_secret: foo
Expand Down
Loading