From 788b92c9aa88870ce37af86871dbee155d8eefa8 Mon Sep 17 00:00:00 2001 From: Dylan Decrulle <81740200+ddecrulle@users.noreply.github.com> Date: Tue, 25 Aug 2026 13:01:17 +0200 Subject: [PATCH 1/9] docs: document AI integration --- SUMMARY.md | 2 + admin-doc/ai-configuration.md | 198 ++++++++++++++++++ .../custom-catalogs/onyxia-extension.md | 20 ++ admin-doc/openid-connect-configuration.md | 5 +- user-doc/ai-providers.md | 82 ++++++++ 5 files changed, 306 insertions(+), 1 deletion(-) create mode 100644 admin-doc/ai-configuration.md create mode 100644 user-doc/ai-providers.md diff --git a/SUMMARY.md b/SUMMARY.md index 9813b43..5837db5 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -18,6 +18,7 @@ * [JSON Schema Support](admin-doc/catalog-of-services/custom-catalogs/json-schema-support.md) * [OpenID Connect Configuration](admin-doc/openid-connect-configuration.md) * [S3 Configuration](admin-doc/s3-configuration.md) +* [AI integration](admin-doc/ai-configuration.md) * [Setting up group projects](admin-doc/setting-up-group-projects.md) * [Security considerations](admin-doc/security-consideration.md) * [Offline / airgap considerations](admin-doc/offline-airgap-considerations.md) @@ -47,6 +48,7 @@ ## user doc * [Getting started with Onyxia](user-doc/user-guide.md) +* [Configure AI providers](user-doc/ai-providers.md) * [Datascience Trainings and Tutorials](user-doc/datascience-trainings-and-tutorials.md) * [Setting up your dev environment in Onyxia](user-doc/setting-up-your-dev-environment-in-onyxia.md) * [Community resources](user-doc/community-resources.md) diff --git a/admin-doc/ai-configuration.md b/admin-doc/ai-configuration.md new file mode 100644 index 0000000..71186d9 --- /dev/null +++ b/admin-doc/ai-configuration.md @@ -0,0 +1,198 @@ +--- +description: Enable AI providers, connect an OpenWebUI gateway, and expose AI credentials to service charts. +icon: robot +--- + +# AI integration + +Onyxia can centralize AI provider settings for a user and inject the selected provider into compatible services at launch time. + +The feature supports two kinds of providers: + +* **Region providers** are OpenWebUI gateways configured by the platform administrator. Onyxia exchanges the user's OIDC access token for a short-lived OpenWebUI token. +* **Custom providers** are configured by users. OpenAI, OpenAI-compatible, Mistral, and Anthropic API protocols are supported. + +{% hint style="info" %} +Enabling the feature adds **My account > AI**. It does not add AI support to every service automatically. A Helm chart must use the [`ai` x-onyxia context](#inject-the-provider-into-a-service) to receive the selected provider. +{% endhint %} + +## Enable the feature + +The feature is disabled by default. Enable it in the Onyxia Web configuration: + +{% code title="apps/onyxia/values.yaml" %} +```yaml +onyxia: + web: + env: + ENABLED_AI: "true" +``` +{% endcode %} + +This is the master switch for both region providers and custom providers. You can enable it without configuring a region provider; users will then only be able to add custom providers. + +The AI tab requires an authenticated user. User preferences and custom provider credentials are stored with the other Onyxia user settings: + +* in the user's Vault-backed configuration when the region has Vault; +* in browser local storage when the region has no Vault. + +## Configure an OpenWebUI gateway + +Add `data.ai` to the existing region configuration. It accepts either one gateway object or a list of gateway objects. + +{% code title="apps/onyxia/values.yaml (region excerpt)" %} +```yaml +onyxia: + api: + regions: + - id: "default" + # Keep the other required region properties here. + data: + # Keep any existing S3 configuration here. + ai: + - id: "openwebui" + name: "Organization AI gateway" + provider: "openai" + URL: "https://ai.example.com" + oauthProvider: "oidc" + oidcConfiguration: + clientID: "onyxia-ai" + description: + en: "Use the models hosted by our organization." + fr: "Utilisez les modèles hébergés par notre organisation." + accountCreation: + title: + en: "Activate your AI account" + fr: "Activez votre compte IA" + description: + en: "Open the gateway and sign in once, then return to Onyxia." + fr: "Ouvrez la passerelle et connectez-vous une première fois, puis revenez dans Onyxia." + buttonLabel: + en: "Open the gateway" + fr: "Ouvrir la passerelle" +``` +{% endcode %} + +Do not add a trailing slash to `URL`. Onyxia derives the API base URL as `/api`. + +### Gateway properties + +| Property | Required | Description | +| --- | --- | --- | +| `URL` | Yes | Public base URL of the OpenWebUI instance. The user's browser must be able to reach it. | +| `oauthProvider` | Yes | OpenWebUI OAuth provider identifier used in `/api/v1/auths/oauth//token/exchange`; commonly `oidc`. | +| `id` | Recommended | Stable, unique identifier used to persist the user's model and default-provider selections. If omitted, it is derived from the gateway's position in the list. | +| `name` | No | Label displayed in Onyxia. Defaults to the hostname from `URL`. | +| `provider` | No | Protocol name injected into charts. Defaults to `openai`, which is appropriate for the OpenWebUI OpenAI-compatible API. | +| `description` | No | String or localized Markdown displayed below the gateway name. | +| `accountCreation` | No | Localized title, description, and button label displayed when OpenWebUI returns `403` because the user has no account yet. The button opens `URL`. | +| `oidcConfiguration` | No | OIDC overrides for this gateway: `issuerURI`, `clientID`, `extraQueryParams`, `scope`, or `idleSessionLifetimeInSeconds`. Unspecified values are inherited from the main Onyxia OIDC configuration. | + +Use an explicit, stable `id` for every gateway. Changing it makes Onyxia treat the gateway as a new provider and discards the model selection associated with the previous identifier. + +### Configure OpenWebUI + +Onyxia uses the following OpenWebUI endpoints directly from the user's browser: + +* `POST /api/v1/auths/oauth//token/exchange` with `{ "token": "" }`; +* `GET /api/models` with the returned token as a Bearer credential. + +Configure OpenWebUI to enable token exchange, trust the OIDC client used by Onyxia, and allow the Onyxia origin through CORS: + +```dotenv +ENABLE_OAUTH_TOKEN_EXCHANGE=true +OAUTH_TOKEN_EXCHANGE_TRUSTED_CLIENT_IDS=onyxia-ai +CORS_ALLOW_ORIGIN=https://onyxia.example.com +``` + +Create `onyxia-ai` as a public OIDC client using Authorization Code Flow with PKCE. Configure the Onyxia URL as an allowed redirect URI. A dedicated client is recommended; if `oidcConfiguration` is omitted, add Onyxia's main client ID to `OAUTH_TOKEN_EXCHANGE_TRUSTED_CLIENT_IDS` instead. + +{% hint style="danger" %} +Use OpenWebUI **0.11.0 or newer** and configure `OAUTH_TOKEN_EXCHANGE_TRUSTED_CLIENT_IDS`. Earlier token-exchange implementations accepted tokens issued to untrusted OAuth clients. The identity provider must support RFC 7662 token introspection; otherwise, leave region gateway token exchange disabled. See the [OpenWebUI SSO documentation](https://docs.openwebui.com/features/authentication-access/auth/sso/#oauth-token-exchange-for-external-applications) and [security advisory](https://github.com/open-webui/open-webui/security/advisories/GHSA-rq84-p6rr-vf89). +{% endhint %} + +The first exchange can return `403` if the user does not yet exist in OpenWebUI. In that case, Onyxia displays the account-creation content. The user must open the gateway, sign in once, return to Onyxia, and select **Refresh credentials**. + +## Inject the provider into a service + +The launcher exposes the user's AI configuration through the [`x-onyxia`](catalog-of-services/custom-catalogs/onyxia-extension.md) context: + +| Context path | Value | +| --- | --- | +| `ai.enabled` | `true` when at least one usable provider is available. | +| `ai.activeProvider` | The provider selected as default, or `undefined`. | +| `ai.providers` | Other usable providers; the active provider is not repeated in this list. | + +Each provider contains `id`, `isDefault`, `name`, `provider`, `apiBase`, `apiKey`, `selectedModel`, and, when model discovery succeeded, `models`. + +The chart decides how these values map to its own `values.yaml`. The following JSON Schema fragment injects the default provider into an `ai` values object: + +{% code title="values.schema.json" %} +```json +{ + "ai": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "x-onyxia": { + "overwriteDefaultWith": "{{ai.enabled}}", + "hidden": true + } + }, + "provider": { + "type": "string", + "default": "", + "x-onyxia": { + "overwriteDefaultWith": "{{ai.activeProvider.provider}}", + "hidden": true + } + }, + "apiBase": { + "type": "string", + "default": "", + "x-onyxia": { + "overwriteDefaultWith": "{{ai.activeProvider.apiBase}}", + "hidden": true + } + }, + "apiKey": { + "type": "string", + "default": "", + "render": "password", + "x-onyxia": { + "overwriteDefaultWith": "{{ai.activeProvider.apiKey}}", + "hidden": true + } + }, + "model": { + "type": "string", + "default": "", + "x-onyxia": { + "overwriteDefaultWith": "{{ai.activeProvider.selectedModel}}", + "hidden": true + } + } + } + } +} +``` +{% endcode %} + +Define matching defaults in `values.yaml` and only create AI-related environment variables or Secrets when `ai.enabled` is `true`. + +{% hint style="warning" %} +`apiKey` is sensitive. Once injected, it becomes part of the Helm values used to launch the service. Store it in a Kubernetes Secret, never a ConfigMap, and do not print it in templates, logs, notes, or post-install instructions. +{% endhint %} + +## Validation checklist + +1. Sign in to Onyxia and open **My account > AI**. +2. Confirm that the gateway appears with the expected name and description. +3. If prompted, open OpenWebUI and sign in once, then refresh the credentials in Onyxia. +4. Confirm that `GET /api/models` loads the model selector. +5. Select a default provider and model. +6. Launch a compatible chart and inspect its generated Helm values to confirm the expected mapping. + +If the AI tab is missing, verify `ENABLED_AI`. If token exchange or model loading fails, check the browser network panel, OpenWebUI's trusted client list, the `oauthProvider` identifier, and CORS for the exact Onyxia origin. diff --git a/admin-doc/catalog-of-services/custom-catalogs/onyxia-extension.md b/admin-doc/catalog-of-services/custom-catalogs/onyxia-extension.md index ae9374c..eea43d5 100644 --- a/admin-doc/catalog-of-services/custom-catalogs/onyxia-extension.md +++ b/admin-doc/catalog-of-services/custom-catalogs/onyxia-extension.md @@ -279,6 +279,12 @@ export type XOnyxiaContext = { useCertManager: boolean; certManagerClusterIssuer: string | undefined; }; + ai: { + enabled: boolean; + activeProvider: AiProvider | undefined; + /** Other usable providers; the active provider is not repeated here. */ + providers: AiProvider[]; + }; proxyInjection: | { enabled: boolean | undefined; @@ -305,8 +311,22 @@ export type XOnyxiaContext = { assert>(); +type AiProvider = { + id: string; + isDefault: boolean; + name: string; + // openai / openai-compatible / mistral / anthropic / ... + provider: string; + apiBase: string; + apiKey: string; + selectedModel: string | undefined; + models: string[] | undefined; +}; + ``` +The `ai` context is populated from the provider and model selected under **My account > AI**. It contains credentials and must be handled as sensitive data. See [AI integration](../../ai-configuration.md#inject-the-provider-into-a-service) for a complete chart example. + You can also concatenate string values using by wrapping the XOnyxia targeted values in `{{}}`. {% code title="values.shema.json" %} diff --git a/admin-doc/openid-connect-configuration.md b/admin-doc/openid-connect-configuration.md index 5de62a4..b1c11cf 100644 --- a/admin-doc/openid-connect-configuration.md +++ b/admin-doc/openid-connect-configuration.md @@ -295,6 +295,9 @@ each service: * **S3 (MinIO STS)** → `onyxia.api.regions[].data.S3.sts.oidcConfiguration` * **Vault** → `onyxia.api.regions[].vault.oidcConfiguration` * **Kubernetes API** → `onyxia.api.regions[].services.k8sPublicEndpoint.oidcConfiguration` +* **AI gateway** → `onyxia.api.regions[].data.ai[].oidcConfiguration` + +AI gateways also require a secure OpenWebUI token-exchange configuration. See [AI integration](ai-configuration.md#configure-openwebui). Each configuration follows this structure: @@ -312,7 +315,7 @@ If no `oidcConfiguration` is provided for a service, Onyxia will reuse the same However, defining a separate OIDC client for each service is recommended to improve access control and security. -You might find it strange that Onyxia requires creating multiple OIDC clients to communicate with different resource servers (e.g. `onyxia-api`, `minio`, `vault`, or the Kubernetes API). You’ll typically end up with several clients such as `onyxia`, `onyxia-vault`, `onyxia-minio`, and `onyxia-kube`.\ +You might find it strange that Onyxia requires creating multiple OIDC clients to communicate with different resource servers (e.g. `onyxia-api`, `minio`, `vault`, the Kubernetes API, or an AI gateway). You’ll typically end up with several clients such as `onyxia`, `onyxia-vault`, `onyxia-minio`, `onyxia-kube`, and `onyxia-ai`.\ At first, this can feel counterintuitive, a _client ID_ seems like it should represent one application, not multiple variants of it. Conceptually, a single client requesting tokens for multiple resource servers (each with its own audience and claims) would make more sense.\ diff --git a/user-doc/ai-providers.md b/user-doc/ai-providers.md new file mode 100644 index 0000000..c2de878 --- /dev/null +++ b/user-doc/ai-providers.md @@ -0,0 +1,82 @@ +--- +description: Select an AI gateway or connect your own AI provider for compatible Onyxia services. +icon: sparkles +--- + +# Configure AI providers + +The **My account > AI** tab lets you choose the AI provider and model that compatible Onyxia services use when they start. + +{% hint style="info" %} +The tab is only visible when your platform administrator has enabled AI integration. A service must also explicitly support Onyxia's AI configuration; selecting a provider does not add AI features to every catalog service. +{% endhint %} + +
The AI tab showing a region gateway and a custom provider

Manage gateway credentials, providers, and model selections from your account.

+ +## Use your platform's AI gateway + +When your administrator provides an AI gateway, Onyxia uses your login session to request a gateway token automatically. + +1. Open **My account > AI**. +2. If Onyxia says that you do not have an account, open the gateway and sign in once. Return to Onyxia and select **Refresh credentials**. +3. Select a model from the gateway's model list. +4. If several providers are available, select **Set default provider** on the one your services should use. + +You can copy the API base URL and token to configure a compatible client manually. Treat the token like a password. It can expire; use **Refresh credentials** to obtain a new one. + +Onyxia remembers the selected model and default provider. The gateway token itself is obtained again from your OIDC session rather than stored as a long-lived credential. + +## Add a custom provider + +You can connect a provider for which you already have an API key: + +1. Under **Custom AI providers**, select **Add a Custom AI Provider**. +2. Enter a name and choose the API protocol. +3. Check the API base URL and enter your API key. +4. Select **Test connection**. Onyxia calls the provider's `/models` endpoint and loads the models available to your key. +5. Select a model, optionally make the provider the default, and save it. + +The supported protocols and default API base URLs are: + +| Protocol | Default API base URL | +| --- | --- | +| OpenAI (native) | `https://api.openai.com/v1` | +| OpenAI-compatible | You must provide the URL. | +| Mistral (native) | `https://api.mistral.ai/v1` | +| Anthropic (native) | `https://api.anthropic.com/v1` | + +Enter the base URL, not the full models or chat-completions endpoint. For example, use `https://api.openai.com/v1`, not `https://api.openai.com/v1/models`. Avoid a trailing slash because Onyxia appends `/models` when testing the connection. + +{% hint style="warning" %} +Onyxia contacts custom providers directly from your browser. The provider must allow cross-origin requests from your Onyxia URL. A connection test can fail even with a valid key if the endpoint's CORS configuration blocks the request. +{% endhint %} + +You can later change the model, edit the provider, make it the default, or delete it. Changing the API base URL or API key requires a new successful connection test before the provider can be saved. + +## Where custom credentials are stored + +Custom provider settings include the API key: + +* If your Onyxia region provides Vault, they are saved with your Vault-backed Onyxia user configuration. +* Without Vault, they are saved in the browser's local storage and are only available in that browser profile. + +Deleting a custom provider removes it from this saved configuration. On a shared computer, sign out and follow your organization's browser-data policy. + +## Use the provider in a service + +After choosing a default provider and model, launch an AI-compatible service from the catalog. Onyxia injects the provider protocol, API base URL, credential, and selected model into the chart when it builds the Helm values. + +The exact behavior inside the service depends on its chart. Consult the service's README to find the relevant environment variables, client configuration, and supported capabilities. + +## Troubleshooting + +| Problem | What to check | +| --- | --- | +| The AI tab is missing | Your administrator must enable the feature, and you must be signed in. | +| The gateway says that you have no account | Open the gateway, sign in once, return to Onyxia, and refresh the credentials. | +| Gateway models do not load | Refresh the credentials. If the error continues, contact the platform administrator. | +| A custom provider test fails | Verify the protocol, base URL, API key, `/models` support, and browser CORS policy. | +| The wrong provider is used by a service | Make the intended provider the default before launching the service. | +| A service receives no AI configuration | The chart must explicitly support Onyxia AI integration; check its README or contact its maintainer. | + +Platform administrators and chart maintainers can find the complete setup in [AI integration](../admin-doc/ai-configuration.md). From e6849034e57e8e7f1396bce82d566755948fc9a1 Mon Sep 17 00:00:00 2001 From: Dylan Decrulle <81740200+ddecrulle@users.noreply.github.com> Date: Tue, 25 Aug 2026 13:10:58 +0200 Subject: [PATCH 2/9] docs: clarify DPoP requirement for AI client --- admin-doc/ai-configuration.md | 4 ++++ admin-doc/openid-connect-configuration.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/admin-doc/ai-configuration.md b/admin-doc/ai-configuration.md index 71186d9..8a32241 100644 --- a/admin-doc/ai-configuration.md +++ b/admin-doc/ai-configuration.md @@ -107,6 +107,10 @@ CORS_ALLOW_ORIGIN=https://onyxia.example.com Create `onyxia-ai` as a public OIDC client using Authorization Code Flow with PKCE. Configure the Onyxia URL as an allowed redirect URI. A dedicated client is recommended; if `oidcConfiguration` is omitted, add Onyxia's main client ID to `OAUTH_TOKEN_EXCHANGE_TRUSTED_CLIENT_IDS` instead. +{% hint style="warning" %} +In Keycloak, leave **Require DPoP bound tokens** disabled for the `onyxia-ai` client. Onyxia hands this client's access token to OpenWebUI's token-exchange endpoint, which reuses it without access to the private key held by the browser and therefore cannot present the associated DPoP proof. This flow requires a standard Bearer access token, even if DPoP remains enabled for other Onyxia clients. See the [Keycloak DPoP documentation](https://www.keycloak.org/securing-apps/dpop). +{% endhint %} + {% hint style="danger" %} Use OpenWebUI **0.11.0 or newer** and configure `OAUTH_TOKEN_EXCHANGE_TRUSTED_CLIENT_IDS`. Earlier token-exchange implementations accepted tokens issued to untrusted OAuth clients. The identity provider must support RFC 7662 token introspection; otherwise, leave region gateway token exchange disabled. See the [OpenWebUI SSO documentation](https://docs.openwebui.com/features/authentication-access/auth/sso/#oauth-token-exchange-for-external-applications) and [security advisory](https://github.com/open-webui/open-webui/security/advisories/GHSA-rq84-p6rr-vf89). {% endhint %} diff --git a/admin-doc/openid-connect-configuration.md b/admin-doc/openid-connect-configuration.md index b1c11cf..45ca8d4 100644 --- a/admin-doc/openid-connect-configuration.md +++ b/admin-doc/openid-connect-configuration.md @@ -297,7 +297,7 @@ each service: * **Kubernetes API** → `onyxia.api.regions[].services.k8sPublicEndpoint.oidcConfiguration` * **AI gateway** → `onyxia.api.regions[].data.ai[].oidcConfiguration` -AI gateways also require a secure OpenWebUI token-exchange configuration. See [AI integration](ai-configuration.md#configure-openwebui). +AI gateways also require a secure OpenWebUI token-exchange configuration. The AI client must issue standard Bearer access tokens rather than DPoP-bound access tokens because OpenWebUI reuses the token during the exchange. See [AI integration](ai-configuration.md#configure-openwebui). Each configuration follows this structure: From fc0a80ed1bd3eafb94a4d5614624d1188333c234 Mon Sep 17 00:00:00 2001 From: Dylan Decrulle <81740200+ddecrulle@users.noreply.github.com> Date: Tue, 25 Aug 2026 13:13:28 +0200 Subject: [PATCH 3/9] docs: describe AI token constraint in OIDC terms --- admin-doc/ai-configuration.md | 2 +- admin-doc/openid-connect-configuration.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/admin-doc/ai-configuration.md b/admin-doc/ai-configuration.md index 8a32241..13f9530 100644 --- a/admin-doc/ai-configuration.md +++ b/admin-doc/ai-configuration.md @@ -108,7 +108,7 @@ CORS_ALLOW_ORIGIN=https://onyxia.example.com Create `onyxia-ai` as a public OIDC client using Authorization Code Flow with PKCE. Configure the Onyxia URL as an allowed redirect URI. A dedicated client is recommended; if `oidcConfiguration` is omitted, add Onyxia's main client ID to `OAUTH_TOKEN_EXCHANGE_TRUSTED_CLIENT_IDS` instead. {% hint style="warning" %} -In Keycloak, leave **Require DPoP bound tokens** disabled for the `onyxia-ai` client. Onyxia hands this client's access token to OpenWebUI's token-exchange endpoint, which reuses it without access to the private key held by the browser and therefore cannot present the associated DPoP proof. This flow requires a standard Bearer access token, even if DPoP remains enabled for other Onyxia clients. See the [Keycloak DPoP documentation](https://www.keycloak.org/securing-apps/dpop). +Configure the OIDC client used for the AI gateway so that the identity provider issues standard Bearer access tokens; do not require DPoP-bound access tokens for this client. Onyxia hands the access token to OpenWebUI's token-exchange endpoint, which reuses it without access to the private key held by the browser and therefore cannot present the associated DPoP proof. This restriction only applies to the AI client; other Onyxia OIDC clients can still use DPoP. {% endhint %} {% hint style="danger" %} diff --git a/admin-doc/openid-connect-configuration.md b/admin-doc/openid-connect-configuration.md index 45ca8d4..ec06abd 100644 --- a/admin-doc/openid-connect-configuration.md +++ b/admin-doc/openid-connect-configuration.md @@ -297,7 +297,7 @@ each service: * **Kubernetes API** → `onyxia.api.regions[].services.k8sPublicEndpoint.oidcConfiguration` * **AI gateway** → `onyxia.api.regions[].data.ai[].oidcConfiguration` -AI gateways also require a secure OpenWebUI token-exchange configuration. The AI client must issue standard Bearer access tokens rather than DPoP-bound access tokens because OpenWebUI reuses the token during the exchange. See [AI integration](ai-configuration.md#configure-openwebui). +AI gateways also require a secure OpenWebUI token-exchange configuration. Configure the associated OIDC client so that the identity provider issues standard Bearer access tokens rather than DPoP-bound access tokens because OpenWebUI reuses the token during the exchange. See [AI integration](ai-configuration.md#configure-openwebui). Each configuration follows this structure: From 91d27497423311786d273cdce2c641d74f7922ce Mon Sep 17 00:00:00 2001 From: Dylan Decrulle <81740200+ddecrulle@users.noreply.github.com> Date: Tue, 25 Aug 2026 13:17:00 +0200 Subject: [PATCH 4/9] Update ai-configuration.md --- admin-doc/ai-configuration.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/admin-doc/ai-configuration.md b/admin-doc/ai-configuration.md index 13f9530..f9d1c22 100644 --- a/admin-doc/ai-configuration.md +++ b/admin-doc/ai-configuration.md @@ -48,7 +48,7 @@ onyxia: - id: "default" # Keep the other required region properties here. data: - # Keep any existing S3 configuration here. + # Keep any existing configuration here. ai: - id: "openwebui" name: "Organization AI gateway" @@ -111,10 +111,6 @@ Create `onyxia-ai` as a public OIDC client using Authorization Code Flow with PK Configure the OIDC client used for the AI gateway so that the identity provider issues standard Bearer access tokens; do not require DPoP-bound access tokens for this client. Onyxia hands the access token to OpenWebUI's token-exchange endpoint, which reuses it without access to the private key held by the browser and therefore cannot present the associated DPoP proof. This restriction only applies to the AI client; other Onyxia OIDC clients can still use DPoP. {% endhint %} -{% hint style="danger" %} -Use OpenWebUI **0.11.0 or newer** and configure `OAUTH_TOKEN_EXCHANGE_TRUSTED_CLIENT_IDS`. Earlier token-exchange implementations accepted tokens issued to untrusted OAuth clients. The identity provider must support RFC 7662 token introspection; otherwise, leave region gateway token exchange disabled. See the [OpenWebUI SSO documentation](https://docs.openwebui.com/features/authentication-access/auth/sso/#oauth-token-exchange-for-external-applications) and [security advisory](https://github.com/open-webui/open-webui/security/advisories/GHSA-rq84-p6rr-vf89). -{% endhint %} - The first exchange can return `403` if the user does not yet exist in OpenWebUI. In that case, Onyxia displays the account-creation content. The user must open the gateway, sign in once, return to Onyxia, and select **Refresh credentials**. ## Inject the provider into a service From d4b2ba5c4d43f1eb0e0b6c857cb2d989c8ec29f9 Mon Sep 17 00:00:00 2001 From: Dylan Decrulle <81740200+ddecrulle@users.noreply.github.com> Date: Tue, 25 Aug 2026 13:38:05 +0200 Subject: [PATCH 5/9] docs: use JSON-style AI region configuration --- admin-doc/ai-configuration.md | 60 +++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/admin-doc/ai-configuration.md b/admin-doc/ai-configuration.md index f9d1c22..b38c132 100644 --- a/admin-doc/ai-configuration.md +++ b/admin-doc/ai-configuration.md @@ -38,38 +38,50 @@ The AI tab requires an authenticated user. User preferences and custom provider ## Configure an OpenWebUI gateway -Add `data.ai` to the existing region configuration. It accepts either one gateway object or a list of gateway objects. +Add `data.ai` to the existing region configuration as a JSON-style array. In `values.yaml`, the flow syntax used below is valid YAML. {% code title="apps/onyxia/values.yaml (region excerpt)" %} ```yaml onyxia: api: - regions: - - id: "default" - # Keep the other required region properties here. - data: - # Keep any existing configuration here. - ai: - - id: "openwebui" - name: "Organization AI gateway" - provider: "openai" - URL: "https://ai.example.com" - oauthProvider: "oidc" - oidcConfiguration: - clientID: "onyxia-ai" - description: - en: "Use the models hosted by our organization." + regions: [ + { + # Keep the other required region properties and existing data configuration here. + data: { + ai: [ + { + id: "openwebui", + name: "Organization AI gateway", + URL: "https://ai.example.com", + oauthProvider: "oidc", + description: { + en: "Use the models hosted by our organization.", fr: "Utilisez les modèles hébergés par notre organisation." - accountCreation: - title: - en: "Activate your AI account" + }, + accountCreation: { + title: { + en: "Activate your AI account", fr: "Activez votre compte IA" - description: - en: "Open the gateway and sign in once, then return to Onyxia." + }, + description: { + en: "Open the gateway and sign in once, then return to Onyxia.", fr: "Ouvrez la passerelle et connectez-vous une première fois, puis revenez dans Onyxia." - buttonLabel: - en: "Open the gateway" + }, + buttonLabel: { + en: "Open the gateway", fr: "Ouvrir la passerelle" + }, + logoURL: "https://ai.example.com/static/logo.png" + }, + oidcConfiguration: { + clientID: "onyxia-ai", + issuerURI: "https://auth.example.com/realms/example" + } + } + ] + } + } + ] ``` {% endcode %} @@ -85,7 +97,7 @@ Do not add a trailing slash to `URL`. Onyxia derives the API base URL as `/ | `name` | No | Label displayed in Onyxia. Defaults to the hostname from `URL`. | | `provider` | No | Protocol name injected into charts. Defaults to `openai`, which is appropriate for the OpenWebUI OpenAI-compatible API. | | `description` | No | String or localized Markdown displayed below the gateway name. | -| `accountCreation` | No | Localized title, description, and button label displayed when OpenWebUI returns `403` because the user has no account yet. The button opens `URL`. | +| `accountCreation` | No | Localized title, description, and button label, plus an optional `logoURL`, displayed when OpenWebUI returns `403` because the user has no account yet. The button opens `URL`. | | `oidcConfiguration` | No | OIDC overrides for this gateway: `issuerURI`, `clientID`, `extraQueryParams`, `scope`, or `idleSessionLifetimeInSeconds`. Unspecified values are inherited from the main Onyxia OIDC configuration. | Use an explicit, stable `id` for every gateway. Changing it makes Onyxia treat the gateway as a new provider and discards the model selection associated with the previous identifier. From 8e1531e58a64a2e926cbca881abd073330176245 Mon Sep 17 00:00:00 2001 From: Dylan Decrulle <81740200+ddecrulle@users.noreply.github.com> Date: Tue, 25 Aug 2026 13:40:28 +0200 Subject: [PATCH 6/9] Update ai-configuration.md --- admin-doc/ai-configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin-doc/ai-configuration.md b/admin-doc/ai-configuration.md index b38c132..ae4c607 100644 --- a/admin-doc/ai-configuration.md +++ b/admin-doc/ai-configuration.md @@ -123,7 +123,7 @@ Create `onyxia-ai` as a public OIDC client using Authorization Code Flow with PK Configure the OIDC client used for the AI gateway so that the identity provider issues standard Bearer access tokens; do not require DPoP-bound access tokens for this client. Onyxia hands the access token to OpenWebUI's token-exchange endpoint, which reuses it without access to the private key held by the browser and therefore cannot present the associated DPoP proof. This restriction only applies to the AI client; other Onyxia OIDC clients can still use DPoP. {% endhint %} -The first exchange can return `403` if the user does not yet exist in OpenWebUI. In that case, Onyxia displays the account-creation content. The user must open the gateway, sign in once, return to Onyxia, and select **Refresh credentials**. +The first exchange can return `403` if the user does not yet exist in OpenWebUI. In that case, Onyxia displays the account-creation content. The user must open the gateway, sign in once, return to Onyxia. ## Inject the provider into a service From 3c7e1e3af686a4d4e427c50dcc1780fb41e1ba97 Mon Sep 17 00:00:00 2001 From: Dylan Decrulle <81740200+ddecrulle@users.noreply.github.com> Date: Wed, 26 Aug 2026 15:03:40 +0200 Subject: [PATCH 7/9] docs: document AI as enabled by default --- admin-doc/ai-configuration.md | 12 ++++++------ user-doc/ai-providers.md | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/admin-doc/ai-configuration.md b/admin-doc/ai-configuration.md index ae4c607..cc64ceb 100644 --- a/admin-doc/ai-configuration.md +++ b/admin-doc/ai-configuration.md @@ -13,23 +13,23 @@ The feature supports two kinds of providers: * **Custom providers** are configured by users. OpenAI, OpenAI-compatible, Mistral, and Anthropic API protocols are supported. {% hint style="info" %} -Enabling the feature adds **My account > AI**. It does not add AI support to every service automatically. A Helm chart must use the [`ai` x-onyxia context](#inject-the-provider-into-a-service) to receive the selected provider. +The AI feature adds **My account > AI**. It does not add AI support to every service automatically. A Helm chart must use the [`ai` x-onyxia context](#inject-the-provider-into-a-service) to receive the selected provider. {% endhint %} -## Enable the feature +## Disable the feature -The feature is disabled by default. Enable it in the Onyxia Web configuration: +The feature is enabled by default. To disable it, set `DISABLE_AI` in the Onyxia Web configuration: {% code title="apps/onyxia/values.yaml" %} ```yaml onyxia: web: env: - ENABLED_AI: "true" + DISABLE_AI: "true" ``` {% endcode %} -This is the master switch for both region providers and custom providers. You can enable it without configuring a region provider; users will then only be able to add custom providers. +This disables both region providers and custom providers. When `DISABLE_AI` is unset or set to `"false"`, authenticated users can access the AI tab. If no region provider is configured, they can still add custom providers. The AI tab requires an authenticated user. User preferences and custom provider credentials are stored with the other Onyxia user settings: @@ -207,4 +207,4 @@ Define matching defaults in `values.yaml` and only create AI-related environment 5. Select a default provider and model. 6. Launch a compatible chart and inspect its generated Helm values to confirm the expected mapping. -If the AI tab is missing, verify `ENABLED_AI`. If token exchange or model loading fails, check the browser network panel, OpenWebUI's trusted client list, the `oauthProvider` identifier, and CORS for the exact Onyxia origin. +If the AI tab is missing, verify that `DISABLE_AI` is not set to `"true"` and that the user is authenticated. If token exchange or model loading fails, check the browser network panel, OpenWebUI's trusted client list, the `oauthProvider` identifier, and CORS for the exact Onyxia origin. diff --git a/user-doc/ai-providers.md b/user-doc/ai-providers.md index c2de878..ee86192 100644 --- a/user-doc/ai-providers.md +++ b/user-doc/ai-providers.md @@ -8,7 +8,7 @@ icon: sparkles The **My account > AI** tab lets you choose the AI provider and model that compatible Onyxia services use when they start. {% hint style="info" %} -The tab is only visible when your platform administrator has enabled AI integration. A service must also explicitly support Onyxia's AI configuration; selecting a provider does not add AI features to every catalog service. +The tab is visible by default for authenticated users unless your platform administrator has disabled AI integration. A service must also explicitly support Onyxia's AI configuration; selecting a provider does not add AI features to every catalog service. {% endhint %}
The AI tab showing a region gateway and a custom provider

Manage gateway credentials, providers, and model selections from your account.

From dbb622f095e6c5bae3af2396583ae2406789cc40 Mon Sep 17 00:00:00 2001 From: Dylan Decrulle <81740200+ddecrulle@users.noreply.github.com> Date: Wed, 26 Aug 2026 15:22:36 +0200 Subject: [PATCH 8/9] docs: move AI gateway config to web env --- admin-doc/ai-configuration.md | 79 +++++++++++------------ admin-doc/openid-connect-configuration.md | 5 +- user-doc/ai-providers.md | 2 +- 3 files changed, 41 insertions(+), 45 deletions(-) diff --git a/admin-doc/ai-configuration.md b/admin-doc/ai-configuration.md index cc64ceb..d9ba940 100644 --- a/admin-doc/ai-configuration.md +++ b/admin-doc/ai-configuration.md @@ -9,7 +9,7 @@ Onyxia can centralize AI provider settings for a user and inject the selected pr The feature supports two kinds of providers: -* **Region providers** are OpenWebUI gateways configured by the platform administrator. Onyxia exchanges the user's OIDC access token for a short-lived OpenWebUI token. +* **Managed providers** are OpenWebUI gateways configured by the platform administrator. Onyxia exchanges the user's OIDC access token for a short-lived OpenWebUI token. * **Custom providers** are configured by users. OpenAI, OpenAI-compatible, Mistral, and Anthropic API protocols are supported. {% hint style="info" %} @@ -29,7 +29,7 @@ onyxia: ``` {% endcode %} -This disables both region providers and custom providers. When `DISABLE_AI` is unset or set to `"false"`, authenticated users can access the AI tab. If no region provider is configured, they can still add custom providers. +This disables both managed providers and custom providers. When `DISABLE_AI` is unset or set to `"false"`, authenticated users can access the AI tab. If no managed provider is configured, they can still add custom providers. The AI tab requires an authenticated user. User preferences and custom provider credentials are stored with the other Onyxia user settings: @@ -38,53 +38,50 @@ The AI tab requires an authenticated user. User preferences and custom provider ## Configure an OpenWebUI gateway -Add `data.ai` to the existing region configuration as a JSON-style array. In `values.yaml`, the flow syntax used below is valid YAML. +Set the `AI` environment variable in the Onyxia Web configuration. Its value is a JSON5 object or array of objects. In `values.yaml`, use a YAML literal block (`|`) so that the JSON5 configuration is passed to Onyxia Web as a string. -{% code title="apps/onyxia/values.yaml (region excerpt)" %} +{% code title="apps/onyxia/values.yaml" %} ```yaml onyxia: - api: - regions: [ - { - # Keep the other required region properties and existing data configuration here. - data: { - ai: [ - { - id: "openwebui", - name: "Organization AI gateway", - URL: "https://ai.example.com", - oauthProvider: "oidc", - description: { - en: "Use the models hosted by our organization.", - fr: "Utilisez les modèles hébergés par notre organisation." + web: + env: + AI: | + [ + { + id: "openwebui", + name: "Organization AI gateway", + provider: "openai", + URL: "https://ai.example.com", + oauthProvider: "oidc", + description: { + en: "Use the models hosted by our organization.", + fr: "Utilisez les modèles hébergés par notre organisation." + }, + accountCreation: { + title: { + en: "Activate your AI account", + fr: "Activez votre compte IA" }, - accountCreation: { - title: { - en: "Activate your AI account", - fr: "Activez votre compte IA" - }, - description: { - en: "Open the gateway and sign in once, then return to Onyxia.", - fr: "Ouvrez la passerelle et connectez-vous une première fois, puis revenez dans Onyxia." - }, - buttonLabel: { - en: "Open the gateway", - fr: "Ouvrir la passerelle" - }, - logoURL: "https://ai.example.com/static/logo.png" + description: { + en: "Open the gateway and sign in once, then return to Onyxia.", + fr: "Ouvrez la passerelle et connectez-vous une première fois, puis revenez dans Onyxia." }, - oidcConfiguration: { - clientID: "onyxia-ai", - issuerURI: "https://auth.example.com/realms/example" + buttonLabel: { + en: "Open the gateway", + fr: "Ouvrir la passerelle" } + }, + oidcConfiguration: { + clientID: "onyxia-ai", + issuerURI: "https://auth.example.com/realms/example" } - ] - } - } - ] + } + ] ``` {% endcode %} +When `AI` is unset or empty, Onyxia does not expose a managed gateway, but users can still configure custom providers. Although a single object is accepted, using an array makes it possible to add more gateways without changing the value's structure. + Do not add a trailing slash to `URL`. Onyxia derives the API base URL as `/api`. ### Gateway properties @@ -97,7 +94,7 @@ Do not add a trailing slash to `URL`. Onyxia derives the API base URL as `/ | `name` | No | Label displayed in Onyxia. Defaults to the hostname from `URL`. | | `provider` | No | Protocol name injected into charts. Defaults to `openai`, which is appropriate for the OpenWebUI OpenAI-compatible API. | | `description` | No | String or localized Markdown displayed below the gateway name. | -| `accountCreation` | No | Localized title, description, and button label, plus an optional `logoURL`, displayed when OpenWebUI returns `403` because the user has no account yet. The button opens `URL`. | +| `accountCreation` | No | Localized title, description, and button label displayed when OpenWebUI returns `403` because the user has no account yet. The button opens `URL`. | | `oidcConfiguration` | No | OIDC overrides for this gateway: `issuerURI`, `clientID`, `extraQueryParams`, `scope`, or `idleSessionLifetimeInSeconds`. Unspecified values are inherited from the main Onyxia OIDC configuration. | Use an explicit, stable `id` for every gateway. Changing it makes Onyxia treat the gateway as a new provider and discards the model selection associated with the previous identifier. @@ -207,4 +204,4 @@ Define matching defaults in `values.yaml` and only create AI-related environment 5. Select a default provider and model. 6. Launch a compatible chart and inspect its generated Helm values to confirm the expected mapping. -If the AI tab is missing, verify that `DISABLE_AI` is not set to `"true"` and that the user is authenticated. If token exchange or model loading fails, check the browser network panel, OpenWebUI's trusted client list, the `oauthProvider` identifier, and CORS for the exact Onyxia origin. +If the AI tab is missing, verify that `DISABLE_AI` is not set to `"true"` and that the user is authenticated. If a managed gateway is missing, validate the JSON5 stored in `AI`, including the required `URL` and `oauthProvider` properties. If token exchange or model loading fails, check the browser network panel, OpenWebUI's trusted client list, the `oauthProvider` identifier, and CORS for the exact Onyxia origin. diff --git a/admin-doc/openid-connect-configuration.md b/admin-doc/openid-connect-configuration.md index ec06abd..8e84ab5 100644 --- a/admin-doc/openid-connect-configuration.md +++ b/admin-doc/openid-connect-configuration.md @@ -289,13 +289,12 @@ Replace `https://my-app.com/` by `https://datalab.my-domain.net/`. Onyxia uses an OIDC client for authentication, but it also connects to other OIDC-enabled services.\ Each of these services **can** have its own OIDC client instance configuration, allowing Onyxia to authenticate using a separate client identity. -In the **region configuration**, you can specify an optional `oidcConfiguration` object for\ -each service: +You can specify an optional `oidcConfiguration` object for each service. Its location depends on how the service is configured: * **S3 (MinIO STS)** → `onyxia.api.regions[].data.S3.sts.oidcConfiguration` * **Vault** → `onyxia.api.regions[].vault.oidcConfiguration` * **Kubernetes API** → `onyxia.api.regions[].services.k8sPublicEndpoint.oidcConfiguration` -* **AI gateway** → `onyxia.api.regions[].data.ai[].oidcConfiguration` +* **AI gateway** → `oidcConfiguration` in each object stored in the `onyxia.web.env.AI` JSON5 value AI gateways also require a secure OpenWebUI token-exchange configuration. Configure the associated OIDC client so that the identity provider issues standard Bearer access tokens rather than DPoP-bound access tokens because OpenWebUI reuses the token during the exchange. See [AI integration](ai-configuration.md#configure-openwebui). diff --git a/user-doc/ai-providers.md b/user-doc/ai-providers.md index ee86192..6f2283c 100644 --- a/user-doc/ai-providers.md +++ b/user-doc/ai-providers.md @@ -11,7 +11,7 @@ The **My account > AI** tab lets you choose the AI provider and model that compa The tab is visible by default for authenticated users unless your platform administrator has disabled AI integration. A service must also explicitly support Onyxia's AI configuration; selecting a provider does not add AI features to every catalog service. {% endhint %} -
The AI tab showing a region gateway and a custom provider

Manage gateway credentials, providers, and model selections from your account.

+
The AI tab showing a managed gateway and a custom provider

Manage gateway credentials, providers, and model selections from your account.

## Use your platform's AI gateway From b6fe8ac63badae7f5a57129dad02154629345181 Mon Sep 17 00:00:00 2001 From: Dylan Decrulle <81740200+ddecrulle@users.noreply.github.com> Date: Fri, 28 Aug 2026 13:25:23 +0200 Subject: [PATCH 9/9] Update ai-configuration.md --- admin-doc/ai-configuration.md | 61 ++++++++++++++++------------------- 1 file changed, 28 insertions(+), 33 deletions(-) diff --git a/admin-doc/ai-configuration.md b/admin-doc/ai-configuration.md index d9ba940..f6ac6eb 100644 --- a/admin-doc/ai-configuration.md +++ b/admin-doc/ai-configuration.md @@ -9,8 +9,8 @@ Onyxia can centralize AI provider settings for a user and inject the selected pr The feature supports two kinds of providers: -* **Managed providers** are OpenWebUI gateways configured by the platform administrator. Onyxia exchanges the user's OIDC access token for a short-lived OpenWebUI token. -* **Custom providers** are configured by users. OpenAI, OpenAI-compatible, Mistral, and Anthropic API protocols are supported. +- **Managed providers** are OpenWebUI gateways configured by the platform administrator. Onyxia exchanges the user's OIDC access token for a short-lived OpenWebUI token. +- **Custom providers** are configured by users. OpenAI, OpenAI-compatible, Mistral, and Anthropic API protocols are supported. {% hint style="info" %} The AI feature adds **My account > AI**. It does not add AI support to every service automatically. A Helm chart must use the [`ai` x-onyxia context](#inject-the-provider-into-a-service) to receive the selected provider. @@ -21,26 +21,29 @@ The AI feature adds **My account > AI**. It does not add AI support to every ser The feature is enabled by default. To disable it, set `DISABLE_AI` in the Onyxia Web configuration: {% code title="apps/onyxia/values.yaml" %} + ```yaml onyxia: web: env: DISABLE_AI: "true" ``` + {% endcode %} This disables both managed providers and custom providers. When `DISABLE_AI` is unset or set to `"false"`, authenticated users can access the AI tab. If no managed provider is configured, they can still add custom providers. The AI tab requires an authenticated user. User preferences and custom provider credentials are stored with the other Onyxia user settings: -* in the user's Vault-backed configuration when the region has Vault; -* in browser local storage when the region has no Vault. +- in the user's Vault-backed configuration when the region has Vault; +- in browser local storage when the region has no Vault. ## Configure an OpenWebUI gateway Set the `AI` environment variable in the Onyxia Web configuration. Its value is a JSON5 object or array of objects. In `values.yaml`, use a YAML literal block (`|`) so that the JSON5 configuration is passed to Onyxia Web as a string. {% code title="apps/onyxia/values.yaml" %} + ```yaml onyxia: web: @@ -78,6 +81,7 @@ onyxia: } ] ``` + {% endcode %} When `AI` is unset or empty, Onyxia does not expose a managed gateway, but users can still configure custom providers. Although a single object is accepted, using an array makes it possible to add more gateways without changing the value's structure. @@ -86,16 +90,16 @@ Do not add a trailing slash to `URL`. Onyxia derives the API base URL as `/ ### Gateway properties -| Property | Required | Description | -| --- | --- | --- | -| `URL` | Yes | Public base URL of the OpenWebUI instance. The user's browser must be able to reach it. | -| `oauthProvider` | Yes | OpenWebUI OAuth provider identifier used in `/api/v1/auths/oauth//token/exchange`; commonly `oidc`. | -| `id` | Recommended | Stable, unique identifier used to persist the user's model and default-provider selections. If omitted, it is derived from the gateway's position in the list. | -| `name` | No | Label displayed in Onyxia. Defaults to the hostname from `URL`. | -| `provider` | No | Protocol name injected into charts. Defaults to `openai`, which is appropriate for the OpenWebUI OpenAI-compatible API. | -| `description` | No | String or localized Markdown displayed below the gateway name. | -| `accountCreation` | No | Localized title, description, and button label displayed when OpenWebUI returns `403` because the user has no account yet. The button opens `URL`. | -| `oidcConfiguration` | No | OIDC overrides for this gateway: `issuerURI`, `clientID`, `extraQueryParams`, `scope`, or `idleSessionLifetimeInSeconds`. Unspecified values are inherited from the main Onyxia OIDC configuration. | +| Property | Required | Description | +| ------------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `URL` | Yes | Public base URL of the OpenWebUI instance. The user's browser must be able to reach it. | +| `oauthProvider` | Yes | OpenWebUI OAuth provider identifier used in `/api/v1/auths/oauth//token/exchange`; commonly `oidc`. | +| `id` | Recommended | Stable, unique identifier used to persist the user's model and default-provider selections. If omitted, it is derived from the gateway's position in the list. | +| `name` | No | Label displayed in Onyxia. Defaults to the hostname from `URL`. | +| `provider` | No | Protocol name injected into charts. Defaults to `openai`, which is appropriate for the OpenWebUI OpenAI-compatible API. | +| `description` | No | String or localized Markdown displayed below the gateway name. | +| `accountCreation` | No | Localized title, description, and button label displayed when OpenWebUI returns `403` because the user has no account yet. The button opens `URL`. | +| `oidcConfiguration` | No | OIDC overrides for this gateway: `issuerURI`, `clientID`, `extraQueryParams`, `scope`, or `idleSessionLifetimeInSeconds`. Unspecified values are inherited from the main Onyxia OIDC configuration. | Use an explicit, stable `id` for every gateway. Changing it makes Onyxia treat the gateway as a new provider and discards the model selection associated with the previous identifier. @@ -103,8 +107,8 @@ Use an explicit, stable `id` for every gateway. Changing it makes Onyxia treat t Onyxia uses the following OpenWebUI endpoints directly from the user's browser: -* `POST /api/v1/auths/oauth//token/exchange` with `{ "token": "" }`; -* `GET /api/models` with the returned token as a Bearer credential. +- `POST /api/v1/auths/oauth//token/exchange` with `{ "token": "" }`; +- `GET /api/models` with the returned token as a Bearer credential. Configure OpenWebUI to enable token exchange, trust the OIDC client used by Onyxia, and allow the Onyxia origin through CORS: @@ -126,17 +130,18 @@ The first exchange can return `403` if the user does not yet exist in OpenWebUI. The launcher exposes the user's AI configuration through the [`x-onyxia`](catalog-of-services/custom-catalogs/onyxia-extension.md) context: -| Context path | Value | -| --- | --- | -| `ai.enabled` | `true` when at least one usable provider is available. | -| `ai.activeProvider` | The provider selected as default, or `undefined`. | -| `ai.providers` | Other usable providers; the active provider is not repeated in this list. | +| Context path | Value | +| ------------------- | ------------------------------------------------------------------------- | +| `ai.enabled` | `true` when at least one usable provider is available. | +| `ai.activeProvider` | The provider selected as default, or `undefined`. | +| `ai.providers` | Other usable providers; the active provider is not repeated in this list. | Each provider contains `id`, `isDefault`, `name`, `provider`, `apiBase`, `apiKey`, `selectedModel`, and, when model discovery succeeded, `models`. The chart decides how these values map to its own `values.yaml`. The following JSON Schema fragment injects the default provider into an `ai` values object: {% code title="values.schema.json" %} + ```json { "ai": { @@ -187,21 +192,11 @@ The chart decides how these values map to its own `values.yaml`. The following J } } ``` + {% endcode %} Define matching defaults in `values.yaml` and only create AI-related environment variables or Secrets when `ai.enabled` is `true`. {% hint style="warning" %} -`apiKey` is sensitive. Once injected, it becomes part of the Helm values used to launch the service. Store it in a Kubernetes Secret, never a ConfigMap, and do not print it in templates, logs, notes, or post-install instructions. +`apiKey` is sensitive. Once injected, it becomes part of the Helm values used to launch the service. {% endhint %} - -## Validation checklist - -1. Sign in to Onyxia and open **My account > AI**. -2. Confirm that the gateway appears with the expected name and description. -3. If prompted, open OpenWebUI and sign in once, then refresh the credentials in Onyxia. -4. Confirm that `GET /api/models` loads the model selector. -5. Select a default provider and model. -6. Launch a compatible chart and inspect its generated Helm values to confirm the expected mapping. - -If the AI tab is missing, verify that `DISABLE_AI` is not set to `"true"` and that the user is authenticated. If a managed gateway is missing, validate the JSON5 stored in `AI`, including the required `URL` and `oauthProvider` properties. If token exchange or model loading fails, check the browser network panel, OpenWebUI's trusted client list, the `oauthProvider` identifier, and CORS for the exact Onyxia origin.