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
2 changes: 2 additions & 0 deletions SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
202 changes: 202 additions & 0 deletions admin-doc/ai-configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
---
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:

- **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.
{% endhint %}

## Disable the feature

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.

## 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:
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"
},
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"
}
},
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 `<URL>/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/<provider>/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 <URL>/api/v1/auths/oauth/<oauthProvider>/token/exchange` with `{ "token": "<OIDC access token>" }`;
- `GET <URL>/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="warning" %}
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.

## 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.
{% endhint %}
20 changes: 20 additions & 0 deletions admin-doc/catalog-of-services/custom-catalogs/onyxia-extension.md
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -305,8 +311,22 @@ export type XOnyxiaContext = {

assert<Equals<XOnyxiaContext["user"]["lang"], Language>>();

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" %}
Expand Down
8 changes: 5 additions & 3 deletions admin-doc/openid-connect-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,12 +289,14 @@ 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** → `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).

Each configuration follows this structure:

Expand All @@ -312,7 +314,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.\
Expand Down
82 changes: 82 additions & 0 deletions user-doc/ai-providers.md
Original file line number Diff line number Diff line change
@@ -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 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 %}

<figure><img src="https://github.com/user-attachments/assets/7bb15d68-d531-4221-9f89-007d0fbb5920" alt="The AI tab showing a managed gateway and a custom provider"><figcaption><p>Manage gateway credentials, providers, and model selections from your account.</p></figcaption></figure>

## 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).