Skip to content

ChatUI ​

Scope: namespaced · Workload: LibreChat via the official chart

The LibreChat web UI, wired to a Gateway. It requires MongoDB and optionally uses Meilisearch for search; both are first-class datastore resources that ChatUI only references.

Spec ​

FieldTypeDescription
secretsRefLocalRef (optional)Same-namespace SecretsManagement to wait for. Leave it out to use plain Kubernetes Secrets you manage yourself — see secretsRef
gatewayRefObjectRefA Gateway (auto-wired if licensed)
gatewayobjectManual endpoint fallback: { url, apiKeySecretRef: { name, key } }. key may be any entry of the Secret (default LITELLM_API_KEY); only that value reaches LibreChat, not the rest of the Secret
models[]listClient-facing model list. The first is the default and titles new chats. Empty = every model the gateway offers (chats are then titled with the model in use): the referenced gateway's model names are listed, and models added later still appear. Required when the gateway is given by gateway.url — its models cannot be discovered
agentsboolLibreChat's Agents endpoint. Disabled by default (interface.agents: false); set true to enable
hoststringUI hostname
ingressobjectclassName, basic-auth, TLS
mongoDatastoreRef (required)LibreChat's MongoDB store
meilisearchMeilisearchRefSearch backend (optional)
subchartsobjectLibreChat subchart toggles (redis/ragApi only)
valuesobjectFree-form Helm-values overlay for the librechat chart (see Custom chart values)
imageVolumeobjectPVC for uploaded images
ssoobjectOIDC/SSO login for LibreChat (see SSO)
mcpRefs[]list of ObjectRefMCPServer CRs to wire in (cross-namespace allowed). Referencing any auto-enables Agents (see MCP servers)

mongo (required) ​

ModeDescription
refA MongoCluster + databaseName (default LibreChat, which must be declared in the cluster's databases[])
externalA connectionSecretRef holding MONGO_URI

MongoDB is required infrastructure, so it is not license-gated.

meilisearch (optional) ​

ModeDescription
ref (default)A MeilisearchInstance
externalhost + masterKeySecretRef
disabledSearch off

The bundled LibreChat MongoDB and Meilisearch subcharts are always disabled — those datastores are managed by their own resources.

What it installs ​

The controller installs the librechat chart as a standalone release in the ChatUI namespace, plus the Forge Gateway config ConfigMap. It translates the resource into chart values (gateway base URL, model list, ingress host + basic-auth, ESO secret names, resolved MONGO_URI / MEILI_HOST, subchart toggles).

For Meilisearch, the controller copies the resolved master key into a same-namespace owned Secret <ui>-meili-key and injects MEILI_MASTER_KEY via global.librechat.env — so a MeilisearchInstance in another namespace still works.

Agents endpoint ​

LibreChat ships its Agents endpoint enabled. The operator turns it off by default — it renders interface.agents: false into librechat.yaml — so a fresh ChatUI does not expose agent building. Opt back in with:

yaml
spec:
  agents: true

Referencing any MCP server also switches Agents on, because LibreChat surfaces MCP tools through them. In that case the operator grants only what the tools need:

How Agents were enableduse (run agents)create (in-UI agent builder)
spec.agents: true (explicit opt-in)✅✅
implicitly, by wiring an MCP server✅❌

This matters because agent creation is not admin-gated in LibreChat: the permissions are emitted as an object rather than a bare true, which would inherit LibreChat's create: true default and show the agent builder to every user. share/public stay off in both cases.

Custom chart values ​

Not every librechat chart option is modelled as a CRD field. spec.values is a free-form object merged into the chart values, so you can set anything the chart supports (replica count, pod resources, extra annotations, …) without waiting for a new CRD field:

yaml
spec:
  values:
    replicaCount: 2
    librechat:
      resources:
        limits: { cpu: "2", memory: 2Gi }

Operator-managed keys win. Your values are the base; the operator's computed values (datastore wiring, secret references, the bundled-subchart enabled toggles, and the tracing/SSO env it injects) are layered on top, so spec.values cannot break the wiring the operator depends on. Use the dedicated fields (mongo, meilisearch, subcharts, agents, sso, …) for anything the operator models; reserve spec.values for the long tail.

Gateway wiring ​

  • With the auto-wiring feature and a gatewayRef, the controller mints a LiteLLMVirtualKey on the referenced Gateway, stores it in an owned Secret, and injects baseURL = http://<gw-svc>.<gw-ns>.svc.cluster.local:4000/v1 plus the key.
  • Without it, supply gateway.{ url, apiKeySecretRef } manually. See Auto-Wiring.

SSO / OIDC login ​

spec.sso enables LibreChat's OpenID Connect provider — it turns on ALLOW_SOCIAL_LOGIN and injects the OPENID_* env. The OAuth client credentials come from a same-namespace Secret (via SecretsManagement); the operator mints the OPENID_SESSION_SECRET itself and wires DOMAIN_SERVER/DOMAIN_CLIENT to the UI's public URL so callbacks resolve.

FieldDescription
issuerURLOIDC issuer / discovery base URL
clientSecretRef.nameSecret holding the OAuth client (keys default to client-id / client-secret)
scopesRequested scopes (default openid, profile, email)
providerNameLogin-button label

The provider, tenantID, and explicit-endpoint fields of the shared SSO type are Gateway-only and ignored here (LibreChat derives endpoints from issuerURL).

yaml
spec:
  sso:
    issuerURL: https://idp.example.com
    providerName: "Acme SSO"
    clientSecretRef: { name: chatui-oidc }

MCP servers ​

spec.mcpRefs wires MCPServer CRs (bundled catalog or external) into LibreChat's Agents endpoint. Referencing any server auto-enables Agents; the operator renders the mcpServers config and, for in-cluster targets, the mcpSettings SSRF allowlist — automatically.

yaml
spec:
  mcpRefs:
    - { name: websearch }            # an MCPServer in this namespace
    - { name: docs, namespace: team } # cross-namespace allowed

Hardened defaults & admin model ​

The operator always renders a hardened LibreChat interface, regardless of MCP usage:

  • Native Web Search and Code Interpreter are OFF (interface.webSearch: false, interface.runCode: false). MCP web_search is the supported web-search path.
  • Users cannot add or disable MCP servers from the UI — admins included (interface.mcpServers permission is locked to use only). Only operator config (your MCPServer CRs) defines them.
  • No real admin: on a fresh ChatUI the operator creates a reserved, never-used phantom admin (random in-Job password, never persisted) to claim LibreChat's "first registered user becomes ADMIN" slot, so all real users (Identity CRs, SSO) land as USER. Pre-existing admins are left untouched.

Example ​

yaml
apiVersion: core.navique.com/v1alpha1
kind: ChatUI
metadata:
  name: forge-ui
  namespace: forge-ui
spec:
  secretsRef: { name: chatui-secrets }
  gatewayRef: { name: gateway, namespace: forge-gateway }
  models: [ azure_ai/gpt-5.4 ]
  agents: false            # default — LibreChat Agents endpoint off
  host: chat.forge.example.com
  mongo:
    mode: ref
    ref: { name: forge-mongo, namespace: forge-data }
    databaseName: LibreChat
  meilisearch:
    mode: ref
    ref: { name: forge-ui-search }
  ingress:
    enabled: true
    className: nginx
    basicAuthSecret: forge-ui-basic-auth
  values:                  # free-form chart overlay (operator keys still win)
    replicaCount: 2

Status ​

Deployment availability and the ingress host, plus the standard conditions and observedGeneration.

Open core under AGPL-3.0. Enterprise components are proprietary and license-gated.