From bfcbce66550d443f68711d6aa5db343f04088684 Mon Sep 17 00:00:00 2001 From: langchain-infra Date: Mon, 27 Jul 2026 13:23:51 -0400 Subject: [PATCH 1/2] fix(langsmith): set AUTH_ENDPOINT on the agent gateway The gateway resolves frontend bearer tokens against the auth service and reads AUTH_ENDPOINT, which the chart never set. Whenever the gateway cannot build a local auth backend it panics at startup with: panic: gateway frontend bearer authentication requires AUTH_ENDPOINT for AUTH_TYPE "mixed" Point AUTH_ENDPOINT at the platform-backend service, the same target LANGSMITH_AUTH_ENDPOINT already uses in the shared ConfigMap. Scoped to the gateway Deployment rather than the ConfigMap so the other services' resolution of AUTH_ENDPOINT is unchanged. Chart version goes to rc.19 rather than rc.18 so this branch and main do not publish different charts under the same version. --- charts/langsmith/Chart.yaml | 2 +- .../templates/agent-gateway/deployment.yaml | 5 ++ .../agent_gateway_auth_endpoint_test.yaml | 47 +++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 charts/langsmith/tests/agent_gateway_auth_endpoint_test.yaml diff --git a/charts/langsmith/Chart.yaml b/charts/langsmith/Chart.yaml index 78a828e8..98d491aa 100644 --- a/charts/langsmith/Chart.yaml +++ b/charts/langsmith/Chart.yaml @@ -5,5 +5,5 @@ maintainers: email: ankush@langchain.dev description: Helm chart to deploy the langsmith application and all services it depends on. type: application -version: 0.16.0-rc.17 +version: 0.16.0-rc.19 appVersion: "0.16.22rc1" diff --git a/charts/langsmith/templates/agent-gateway/deployment.yaml b/charts/langsmith/templates/agent-gateway/deployment.yaml index 33a513ca..b0118474 100644 --- a/charts/langsmith/templates/agent-gateway/deployment.yaml +++ b/charts/langsmith/templates/agent-gateway/deployment.yaml @@ -1,6 +1,11 @@ {{- define "agentGatewayEnvVars" -}} - name: PORT value: {{ .Values.agentGateway.containerPort | quote }} +# The gateway resolves frontend bearer tokens against the auth service. It +# reads AUTH_ENDPOINT (not LANGSMITH_AUTH_ENDPOINT) and panics at startup if +# it is unset for any authType other than "none". +- name: AUTH_ENDPOINT + value: "http://{{ include "langsmith.fullname" . }}-{{ .Values.platformBackend.name }}.{{ .Values.namespace | default .Release.Namespace }}.svc.{{ .Values.clusterDomain }}:{{ .Values.platformBackend.service.port }}" {{- if .Values.presidioAnalyzer.enabled }} - name: PRESIDIO_ANALYZER_URL value: "http://{{ include "langsmith.fullname" . }}-{{ .Values.presidioAnalyzer.name }}.{{ .Values.namespace | default .Release.Namespace }}.svc.{{ .Values.clusterDomain }}:{{ .Values.presidioAnalyzer.service.port }}" diff --git a/charts/langsmith/tests/agent_gateway_auth_endpoint_test.yaml b/charts/langsmith/tests/agent_gateway_auth_endpoint_test.yaml new file mode 100644 index 00000000..0fbb4bf4 --- /dev/null +++ b/charts/langsmith/tests/agent_gateway_auth_endpoint_test.yaml @@ -0,0 +1,47 @@ +suite: Agent gateway auth endpoint +templates: + - agent-gateway/deployment.yaml + # Loaded so the Deployment's `langsmith.checksumAnnotations` includes resolve. + - config-map.yaml + - frontend/config-map.yaml + - secrets.yaml + - redis/secrets.yaml + - postgres/secrets.yaml + - clickhouse/secrets.yaml +tests: + - it: sets AUTH_ENDPOINT to the platform-backend service + template: agent-gateway/deployment.yaml + set: + agentGateway.enabled: true + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: AUTH_ENDPOINT + value: "http://RELEASE-NAME-langsmith-platform-backend.NAMESPACE.svc.cluster.local:1986" + + - it: sets AUTH_ENDPOINT under oauth authType + template: agent-gateway/deployment.yaml + set: + agentGateway.enabled: true + config.authType: oauth + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: AUTH_ENDPOINT + value: "http://RELEASE-NAME-langsmith-platform-backend.NAMESPACE.svc.cluster.local:1986" + + - it: honours a custom platform-backend name, port and clusterDomain + template: agent-gateway/deployment.yaml + set: + agentGateway.enabled: true + clusterDomain: cluster.example + platformBackend.name: pb + platformBackend.service.port: 9999 + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: AUTH_ENDPOINT + value: "http://RELEASE-NAME-langsmith-pb.NAMESPACE.svc.cluster.example:9999" From 8cda356175a06b24f466ccb8c88aa9e25fd7689a Mon Sep 17 00:00:00 2001 From: langchain-infra Date: Tue, 28 Jul 2026 18:25:07 -0400 Subject: [PATCH 2/2] refactor(langsmith): move AUTH_ENDPOINT to the shared ConfigMap AUTH_ENDPOINT was set as an inline env var on the agent gateway Deployment only. Move it to the shared ConfigMap alongside GO_ENDPOINT and LANGSMITH_AUTH_ENDPOINT, which already resolve to the same platform-backend service. The gateway already consumes the shared ConfigMap via envFrom, so it still receives the value. Setting it centrally also covers every other consumer of AUTH_ENDPOINT instead of the single Deployment we happened to patch. Replace the gateway-scoped test with a ConfigMap suite covering the key's presence across each authType branch, that it matches LANGSMITH_AUTH_ENDPOINT, custom platformBackend name/port/clusterDomain, and the gateway's envFrom reference that delivers it. --- .../templates/agent-gateway/deployment.yaml | 5 - charts/langsmith/templates/config-map.yaml | 5 + .../agent_gateway_auth_endpoint_test.yaml | 47 --------- .../langsmith/tests/auth_endpoint_test.yaml | 97 +++++++++++++++++++ 4 files changed, 102 insertions(+), 52 deletions(-) delete mode 100644 charts/langsmith/tests/agent_gateway_auth_endpoint_test.yaml create mode 100644 charts/langsmith/tests/auth_endpoint_test.yaml diff --git a/charts/langsmith/templates/agent-gateway/deployment.yaml b/charts/langsmith/templates/agent-gateway/deployment.yaml index b0118474..33a513ca 100644 --- a/charts/langsmith/templates/agent-gateway/deployment.yaml +++ b/charts/langsmith/templates/agent-gateway/deployment.yaml @@ -1,11 +1,6 @@ {{- define "agentGatewayEnvVars" -}} - name: PORT value: {{ .Values.agentGateway.containerPort | quote }} -# The gateway resolves frontend bearer tokens against the auth service. It -# reads AUTH_ENDPOINT (not LANGSMITH_AUTH_ENDPOINT) and panics at startup if -# it is unset for any authType other than "none". -- name: AUTH_ENDPOINT - value: "http://{{ include "langsmith.fullname" . }}-{{ .Values.platformBackend.name }}.{{ .Values.namespace | default .Release.Namespace }}.svc.{{ .Values.clusterDomain }}:{{ .Values.platformBackend.service.port }}" {{- if .Values.presidioAnalyzer.enabled }} - name: PRESIDIO_ANALYZER_URL value: "http://{{ include "langsmith.fullname" . }}-{{ .Values.presidioAnalyzer.name }}.{{ .Values.namespace | default .Release.Namespace }}.svc.{{ .Values.clusterDomain }}:{{ .Values.presidioAnalyzer.service.port }}" diff --git a/charts/langsmith/templates/config-map.yaml b/charts/langsmith/templates/config-map.yaml index 61f4b252..c83a0dab 100644 --- a/charts/langsmith/templates/config-map.yaml +++ b/charts/langsmith/templates/config-map.yaml @@ -41,6 +41,11 @@ data: SMITH_BACKEND_ENDPOINT: "http://{{ include "langsmith.fullname" . }}-{{.Values.backend.name}}.{{ .Values.namespace | default .Release.Namespace }}.svc.{{ .Values.clusterDomain }}:{{ .Values.backend.service.port }}" HOST_BACKEND_ENDPOINT: "http://{{ include "langsmith.fullname" . }}-{{.Values.hostBackend.name}}.{{ .Values.namespace | default .Release.Namespace }}.svc.{{ .Values.clusterDomain }}:{{ .Values.hostBackend.service.port }}" LANGSMITH_AUTH_ENDPOINT: "http://{{ include "langsmith.fullname" . }}-{{ .Values.platformBackend.name }}.{{ .Values.namespace | default .Release.Namespace }}.svc.{{ .Values.clusterDomain }}:{{ .Values.platformBackend.service.port }}" + # Distinct from LANGSMITH_AUTH_ENDPOINT: consumers that resolve auth against + # the auth service read AUTH_ENDPOINT. In a single-cluster install the auth + # service is the platform backend, so both point there. The agent gateway + # panics at startup without it for any authType other than "none". + AUTH_ENDPOINT: "http://{{ include "langsmith.fullname" . }}-{{ .Values.platformBackend.name }}.{{ .Values.namespace | default .Release.Namespace }}.svc.{{ .Values.clusterDomain }}:{{ .Values.platformBackend.service.port }}" CLICKHOUSE_INGESTION_ENABLED: {{ .Values.clickhouse.enabled | quote }} CLICKHOUSE_QUERY_ENABLED: {{ .Values.clickhouse.enabled | quote }} SMITHDB_INGESTION_ENABLED: {{ .Values.smithdb.langsmith.ingestion.enabled | quote }} diff --git a/charts/langsmith/tests/agent_gateway_auth_endpoint_test.yaml b/charts/langsmith/tests/agent_gateway_auth_endpoint_test.yaml deleted file mode 100644 index 0fbb4bf4..00000000 --- a/charts/langsmith/tests/agent_gateway_auth_endpoint_test.yaml +++ /dev/null @@ -1,47 +0,0 @@ -suite: Agent gateway auth endpoint -templates: - - agent-gateway/deployment.yaml - # Loaded so the Deployment's `langsmith.checksumAnnotations` includes resolve. - - config-map.yaml - - frontend/config-map.yaml - - secrets.yaml - - redis/secrets.yaml - - postgres/secrets.yaml - - clickhouse/secrets.yaml -tests: - - it: sets AUTH_ENDPOINT to the platform-backend service - template: agent-gateway/deployment.yaml - set: - agentGateway.enabled: true - asserts: - - contains: - path: spec.template.spec.containers[0].env - content: - name: AUTH_ENDPOINT - value: "http://RELEASE-NAME-langsmith-platform-backend.NAMESPACE.svc.cluster.local:1986" - - - it: sets AUTH_ENDPOINT under oauth authType - template: agent-gateway/deployment.yaml - set: - agentGateway.enabled: true - config.authType: oauth - asserts: - - contains: - path: spec.template.spec.containers[0].env - content: - name: AUTH_ENDPOINT - value: "http://RELEASE-NAME-langsmith-platform-backend.NAMESPACE.svc.cluster.local:1986" - - - it: honours a custom platform-backend name, port and clusterDomain - template: agent-gateway/deployment.yaml - set: - agentGateway.enabled: true - clusterDomain: cluster.example - platformBackend.name: pb - platformBackend.service.port: 9999 - asserts: - - contains: - path: spec.template.spec.containers[0].env - content: - name: AUTH_ENDPOINT - value: "http://RELEASE-NAME-langsmith-pb.NAMESPACE.svc.cluster.example:9999" diff --git a/charts/langsmith/tests/auth_endpoint_test.yaml b/charts/langsmith/tests/auth_endpoint_test.yaml new file mode 100644 index 00000000..729af879 --- /dev/null +++ b/charts/langsmith/tests/auth_endpoint_test.yaml @@ -0,0 +1,97 @@ +suite: AUTH_ENDPOINT shared config +# insights/polly are enabled by default on this chart and would otherwise require +# encryption keys to pass validate.yaml (which renders for every test). validate +# also requires a license, a salt, and one of basic auth / OAuth to be enabled. +# +# The suite default is mixed + OAuth with basic auth off: the combination that +# crash-looped the gateway, because it is the one where the gateway cannot build +# a local auth handler and must resolve tokens against AUTH_ENDPOINT instead. +set: + insights.enabled: false + polly.enabled: false + config.langsmithLicenseKey: "lic" + config.apiKeySalt: "salt" + config.oauth.enabled: true + config.authType: "mixed" +tests: + - it: points AUTH_ENDPOINT at the platform backend + template: templates/config-map.yaml + asserts: + - equal: + path: data.AUTH_TYPE + value: "mixed" + - equal: + path: data.BASIC_AUTH_ENABLED + value: "false" + - equal: + path: data.AUTH_ENDPOINT + value: "http://RELEASE-NAME-langsmith-platform-backend.NAMESPACE.svc.cluster.local:1986" + + # AUTH_ENDPOINT must resolve to the same service as LANGSMITH_AUTH_ENDPOINT. + # They are separate keys read by different consumers, so nothing else keeps + # them in sync. + - it: matches LANGSMITH_AUTH_ENDPOINT + template: templates/config-map.yaml + asserts: + - equal: + path: data.LANGSMITH_AUTH_ENDPOINT + value: "http://RELEASE-NAME-langsmith-platform-backend.NAMESPACE.svc.cluster.local:1986" + - equal: + path: data.AUTH_ENDPOINT + value: "http://RELEASE-NAME-langsmith-platform-backend.NAMESPACE.svc.cluster.local:1986" + + # The authType if/else chain sits directly above these keys; the next three + # cases pin AUTH_ENDPOINT outside it so no branch can drop it. + - it: is set under oauth authType + template: templates/config-map.yaml + set: + config.authType: "oauth" + asserts: + - equal: + path: data.AUTH_TYPE + value: "oauth" + - equal: + path: data.AUTH_ENDPOINT + value: "http://RELEASE-NAME-langsmith-platform-backend.NAMESPACE.svc.cluster.local:1986" + + - it: is set under mixed authType with basic auth + template: templates/config-map.yaml + set: + config.oauth.enabled: false + config.basicAuth.enabled: true + config.initialOrgAdminEmail: "admin@example.com" + config.basicAuth.initialOrgAdminPassword: "TestLangSmith123!" + asserts: + - equal: + path: data.AUTH_TYPE + value: "mixed" + - equal: + path: data.BASIC_AUTH_ENABLED + value: "true" + - equal: + path: data.AUTH_ENDPOINT + value: "http://RELEASE-NAME-langsmith-platform-backend.NAMESPACE.svc.cluster.local:1986" + + - it: honours a custom platform-backend name, port and clusterDomain + template: templates/config-map.yaml + set: + clusterDomain: cluster.example + platformBackend.name: pb + platformBackend.service.port: 9999 + asserts: + - equal: + path: data.AUTH_ENDPOINT + value: "http://RELEASE-NAME-langsmith-pb.NAMESPACE.svc.cluster.example:9999" + + # The gateway reads AUTH_ENDPOINT from the shared ConfigMap via envFrom rather + # than an inline env entry, so that reference is what delivers it. + - it: is delivered to the agent gateway via envFrom + template: templates/agent-gateway/deployment.yaml + set: + agentGateway.enabled: true + asserts: + - contains: + path: spec.template.spec.containers[0].envFrom + content: + configMapRef: + name: RELEASE-NAME-langsmith-config