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
1 change: 1 addition & 0 deletions app/MindWork AI Studio/wwwroot/changelog/v26.3.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- Added a start-page setting, so AI Studio can now open directly on your preferred page when the app starts. Configuration plugins can also provide and optionally lock this default for organizations.
- Added math rendering in chats for LaTeX display formulas, including block formats such as `$$ ... $$` and `\[ ... \]`.
- Released the document analysis assistant after an intense testing phase.
- Improved enterprise deployment for organizations: administrators can now provide up to 10 centrally managed enterprise configuration slots, use policy files on Linux and macOS, and continue using older configuration formats as a fallback during migration.
- Improved the profile selection for assistants and the chat. You can now explicitly choose between the app default profile, no profile, or a specific profile.
- Improved the performance by caching the OS language detection and requesting the user language only once per app start.
- Improved the chat performance by reducing unnecessary UI updates, making chats smoother and more responsive, especially in longer conversations.
Expand Down
164 changes: 80 additions & 84 deletions documentation/Enterprise IT.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,123 +15,118 @@ AI Studio checks about every 16 minutes to see if the configuration ID, the serv
## Configure the devices
So that MindWork AI Studio knows where to load which configuration, this information must be provided as metadata on employees' devices. Currently, the following options are available:

- **Registry** (only available for Microsoft Windows): On Windows devices, AI Studio first tries to read the information from the registry. The registry information can be managed and distributed centrally as a so-called Group Policy Object (GPO).
- **Windows Registry / GPO**: On Windows, AI Studio first tries to read the enterprise configuration metadata from the registry. This is the preferred option for centrally managed Windows devices.

- **Environment variables**: On all operating systems (on Windows as a fallback after the registry), AI Studio tries to read the configuration metadata from environment variables.
- **Policy files**: AI Studio can read simple YAML policy files from a system-wide directory. On Linux and macOS, this is the preferred option. On Windows, it is used as a fallback after the registry.

### Multiple configurations (recommended)
- **Environment variables**: Environment variables are still supported on all operating systems, but they are now only used as the last fallback.

AI Studio supports loading multiple enterprise configurations simultaneously. This enables hierarchical configuration schemes, e.g., organization-wide settings combined with department-specific settings. The following keys and variables are used:
### Source order and fallback behavior

- Key `HKEY_CURRENT_USER\Software\github\MindWork AI Studio\Enterprise IT`, value `configs` or variable `MINDWORK_AI_STUDIO_ENTERPRISE_CONFIGS`: A combined format containing one or more configuration entries. Each entry consists of a configuration ID and a server URL separated by `@`. Multiple entries are separated by `;`. The format is: `id1@url1;id2@url2;id3@url3`. The configuration ID must be a valid [GUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Globally_unique_identifier).
AI Studio does **not** merge the registry, policy files, and environment variables. Instead, it checks them in order:

- Key `HKEY_CURRENT_USER\Software\github\MindWork AI Studio\Enterprise IT`, value `config_encryption_secret` or variable `MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_ENCRYPTION_SECRET`: A base64-encoded 32-byte encryption key for decrypting API keys in configuration plugins. This is optional and only needed if you want to include encrypted API keys in your configuration. All configurations share the same encryption secret.
- **Windows:** Registry -> Policy files -> Environment variables
- **Linux:** Policy files -> Environment variables
- **macOS:** Policy files -> Environment variables

**Example:** To configure two enterprise configurations (one for the organization and one for a department):
For enterprise configurations, AI Studio uses the **first source that contains at least one valid enterprise configuration**.

```
MINDWORK_AI_STUDIO_ENTERPRISE_CONFIGS=9072b77d-ca81-40da-be6a-861da525ef7b@https://intranet.my-company.com:30100/ai-studio/configuration;a1b2c3d4-e5f6-7890-abcd-ef1234567890@https://intranet.my-company.com:30100/ai-studio/department-config
```
For the encryption secret, AI Studio uses the **first source that contains a non-empty encryption secret**, even if that source does not contain any enterprise configuration IDs or server URLs. This allows secret-only setups during migration or on machines that only need encrypted API key support.

**Priority:** When multiple configurations define the same setting (e.g., a provider with the same ID), the first definition wins. The order of entries in the variable determines priority. Place the organization-wide configuration first, followed by department-specific configurations if the organization should have higher priority.
### Multiple configurations (recommended)

### Windows GPO / PowerShell example for `configs`
AI Studio supports loading multiple enterprise configurations simultaneously. This enables hierarchical configuration schemes, such as organization-wide settings combined with institute- or department-specific settings.

If you distribute multiple GPOs, each GPO should read and write the same registry value (`configs`) and only update its own `id@url` entry. Other entries must stay untouched.
The preferred format is a fixed set of indexed pairs:

The following PowerShell example provides helper functions for appending and removing entries safely:
- Registry values `config_id0` to `config_id9` together with `config_server_url0` to `config_server_url9`
- Environment variables `MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_ID0` to `MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_ID9` together with `MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_SERVER_URL0` to `MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_SERVER_URL9`
- Policy files `config0.yaml` to `config9.yaml`

```powershell
$RegistryPath = "HKCU:\Software\github\MindWork AI Studio\Enterprise IT"
$ConfigsValueName = "configs"
Each configuration ID must be a valid [GUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Globally_unique_identifier). Up to ten configurations are supported per device.

function Get-ConfigEntries {
param([string]$RawValue)
If multiple configurations define the same setting, the first definition wins. For indexed pairs and policy files, the order is slot `0`, then `1`, and so on up to `9`.

if ([string]::IsNullOrWhiteSpace($RawValue)) { return @() }
### Windows registry example

$entries = @()
foreach ($part in $RawValue.Split(';')) {
$trimmed = $part.Trim()
if ([string]::IsNullOrWhiteSpace($trimmed)) { continue }
The Windows registry path is:

$pair = $trimmed.Split('@', 2)
if ($pair.Count -ne 2) { continue }
`HKEY_CURRENT_USER\Software\github\MindWork AI Studio\Enterprise IT`

$id = $pair[0].Trim().ToLowerInvariant()
$url = $pair[1].Trim()
if ([string]::IsNullOrWhiteSpace($id) -or [string]::IsNullOrWhiteSpace($url)) { continue }
Example values:

$entries += [PSCustomObject]@{
Id = $id
Url = $url
}
}
- `config_id0` = `9072b77d-ca81-40da-be6a-861da525ef7b`
- `config_server_url0` = `https://intranet.example.org/ai-studio/configuration`
- `config_id1` = `a1b2c3d4-e5f6-7890-abcd-ef1234567890`
- `config_server_url1` = `https://intranet.example.org/ai-studio/department-config`
- `config_encryption_secret` = `BASE64...`

return $entries
}
This approach works well with GPOs because each slot can be managed independently without rewriting a shared combined string.

function ConvertTo-ConfigValue {
param([array]$Entries)
### Policy files

return ($Entries | ForEach-Object { "$($_.Id)@$($_.Url)" }) -join ';'
}
#### Windows policy directory

function Add-EnterpriseConfigEntry {
param(
[Parameter(Mandatory=$true)][Guid]$ConfigId,
[Parameter(Mandatory=$true)][string]$ServerUrl
)
`%ProgramData%\MindWorkAI\AI-Studio\`

if (-not (Test-Path $RegistryPath)) {
New-Item -Path $RegistryPath -Force | Out-Null
}
#### Linux policy directories

$raw = (Get-ItemProperty -Path $RegistryPath -Name $ConfigsValueName -ErrorAction SilentlyContinue).$ConfigsValueName
$entries = Get-ConfigEntries -RawValue $raw
$normalizedId = $ConfigId.ToString().ToLowerInvariant()
$normalizedUrl = $ServerUrl.Trim()
AI Studio checks each directory listed in `$XDG_CONFIG_DIRS` and looks for a `mindwork-ai-studio` subdirectory in each one. If `$XDG_CONFIG_DIRS` is empty or not set, AI Studio falls back to:

# Replace only this one ID, keep all other entries unchanged.
$entries = @($entries | Where-Object { $_.Id -ne $normalizedId })
$entries += [PSCustomObject]@{
Id = $normalizedId
Url = $normalizedUrl
}
`/etc/xdg/mindwork-ai-studio/`

Set-ItemProperty -Path $RegistryPath -Name $ConfigsValueName -Type String -Value (ConvertTo-ConfigValue -Entries $entries)
}
The directories from `$XDG_CONFIG_DIRS` are processed in order.

function Remove-EnterpriseConfigEntry {
param(
[Parameter(Mandatory=$true)][Guid]$ConfigId
)
#### macOS policy directory

if (-not (Test-Path $RegistryPath)) { return }
`/Library/Application Support/MindWork/AI Studio/`

$raw = (Get-ItemProperty -Path $RegistryPath -Name $ConfigsValueName -ErrorAction SilentlyContinue).$ConfigsValueName
$entries = Get-ConfigEntries -RawValue $raw
$normalizedId = $ConfigId.ToString().ToLowerInvariant()
#### Policy file names and content

# Remove only this one ID, keep all other entries unchanged.
$updated = @($entries | Where-Object { $_.Id -ne $normalizedId })
Set-ItemProperty -Path $RegistryPath -Name $ConfigsValueName -Type String -Value (ConvertTo-ConfigValue -Entries $updated)
}
Configuration files:

- `config0.yaml`
- `config1.yaml`
- ...
- `config9.yaml`

Each configuration file contains one configuration ID and one server URL:

```yaml
id: "9072b77d-ca81-40da-be6a-861da525ef7b"
server_url: "https://intranet.example.org/ai-studio/configuration"
```

# Example usage:
# Add-EnterpriseConfigEntry -ConfigId "9072b77d-ca81-40da-be6a-861da525ef7b" -ServerUrl "https://intranet.example.org:30100/ai-studio/configuration"
# Remove-EnterpriseConfigEntry -ConfigId "9072b77d-ca81-40da-be6a-861da525ef7b"
Optional encryption secret file:

- `config_encryption_secret.yaml`

```yaml
config_encryption_secret: "BASE64..."
```

### Single configuration (legacy)
### Environment variable example

If you need the fallback environment-variable format, configure the values like this:

```bash
MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_ID0=9072b77d-ca81-40da-be6a-861da525ef7b
MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_SERVER_URL0=https://intranet.example.org/ai-studio/configuration
MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_ID1=a1b2c3d4-e5f6-7890-abcd-ef1234567890
MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_SERVER_URL1=https://intranet.example.org/ai-studio/department-config
MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_ENCRYPTION_SECRET=BASE64...
```

The following single-configuration keys and variables are still supported for backwards compatibility. AI Studio always reads both the multi-config and legacy variables and merges all found configurations into one list. If a configuration ID appears in both, the entry from the multi-config format takes priority (first occurrence wins). This means you can migrate to the new format incrementally without losing existing configurations:
### Legacy formats (still supported)

- Key `HKEY_CURRENT_USER\Software\github\MindWork AI Studio\Enterprise IT`, value `config_id` or variable `MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_ID`: This must be a valid [GUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Globally_unique_identifier). It uniquely identifies the configuration. You can use an ID per department, institute, or even per person.
The following older formats are still supported for backwards compatibility:

- Key `HKEY_CURRENT_USER\Software\github\MindWork AI Studio\Enterprise IT`, value `config_server_url` or variable `MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_SERVER_URL`: An HTTP or HTTPS address using an IP address or DNS name. This is the web server from which AI Studio attempts to load the specified configuration as a ZIP file.
- Registry value `configs` or environment variable `MINDWORK_AI_STUDIO_ENTERPRISE_CONFIGS`: Combined format `id1@url1;id2@url2;...`
- Registry value `config_id` or environment variable `MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_ID`
- Registry value `config_server_url` or environment variable `MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_SERVER_URL`
- Registry value `config_encryption_secret` or environment variable `MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_ENCRYPTION_SECRET`

- Key `HKEY_CURRENT_USER\Software\github\MindWork AI Studio\Enterprise IT`, value `config_encryption_secret` or variable `MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_ENCRYPTION_SECRET`: A base64-encoded 32-byte encryption key for decrypting API keys in configuration plugins. This is optional and only needed if you want to include encrypted API keys in your configuration.
Within a single source, AI Studio reads the new indexed pairs first, then the combined legacy format, and finally the legacy single-configuration format. This makes it possible to migrate gradually without breaking older setups.

### How configurations are downloaded

Expand Down Expand Up @@ -183,7 +178,7 @@ intranet.my-company.com:30100 {

## Important: Plugin ID must match the enterprise configuration ID

The `ID` field inside your configuration plugin (the Lua file) **must** be identical to the enterprise configuration ID used in the registry or environment variable. AI Studio uses this ID to match downloaded configurations to their plugins. If the IDs do not match, AI Studio will log a warning and the configuration may not be displayed correctly on the Information page.
The `ID` field inside your configuration plugin (the Lua file) **must** be identical to the enterprise configuration ID configured on the client device, whether it comes from the registry, a policy file, or an environment variable. AI Studio uses this ID to match downloaded configurations to their plugins. If the IDs do not match, AI Studio will log a warning and the configuration may not be displayed correctly on the Information page.

For example, if your enterprise configuration ID is `9072b77d-ca81-40da-be6a-861da525ef7b`, then your plugin must declare:

Expand Down Expand Up @@ -233,9 +228,10 @@ You can include encrypted API keys in your configuration plugins for cloud provi
In AI Studio, enable the "Show administration settings" toggle in the app settings. Then click the "Generate encryption secret and copy to clipboard" button in the "Enterprise Administration" section. This generates a cryptographically secure 256-bit key and copies it to your clipboard as a base64 string.

2. **Deploy the encryption secret:**
Distribute the secret to all client machines via Group Policy (Windows Registry) or environment variables:
- Registry: `HKEY_CURRENT_USER\Software\github\MindWork AI Studio\Enterprise IT\config_encryption_secret`
- Environment: `MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_ENCRYPTION_SECRET`
Distribute the secret to all client machines using any supported enterprise source. The secret can be deployed on its own, even when no enterprise configuration IDs or server URLs are defined on that machine:
- Windows Registry / GPO: `HKEY_CURRENT_USER\Software\github\MindWork AI Studio\Enterprise IT\config_encryption_secret`
- Policy file: `config_encryption_secret.yaml`
- Environment fallback: `MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_ENCRYPTION_SECRET`

You must also deploy the same secret on the machine where you will export the encrypted API keys (step 3).

Expand Down
Loading
Loading