mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-10-16 01:34:28 +00:00
Added user-managed API keys for enterprise-configured providers (#919)
Build and Release / Determine run mode (push) Waiting to run
Build and Release / Read metadata (push) Blocked by required conditions
Build and Release / Sync Flatpak repo (push) Blocked by required conditions
Build and Release / Collect Flatpak artifacts (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg,app,updater, dmg) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis,updater, nsis) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage,updater, appimage) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg,app,updater, dmg) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis,updater, nsis) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage,updater, appimage) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Build and Release / Determine run mode (push) Waiting to run
Build and Release / Read metadata (push) Blocked by required conditions
Build and Release / Sync Flatpak repo (push) Blocked by required conditions
Build and Release / Collect Flatpak artifacts (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg,app,updater, dmg) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis,updater, nsis) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage,updater, appimage) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg,app,updater, dmg) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis,updater, nsis) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage,updater, appimage) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Co-authored-by: Thorsten Sommer <SommerEngineering@users.noreply.github.com>
This commit is contained in:
1 parent
a9a37b6bf5
commit
592c9c76e2
23 files changed
+479
-50
No files matched your search
@@ -20,7 +20,8 @@ public sealed record EmbeddingProvider(
|
||||
bool IsEnterpriseConfiguration = false,
|
||||
Guid EnterpriseConfigurationPluginId = default,
|
||||
string Hostname = "http://localhost:1234",
|
||||
Host Host = Host.NONE) : ConfigurationBaseObject, ISecretId
|
||||
Host Host = Host.NONE,
|
||||
bool AllowUserProvidedAPIKey = false) : ConfigurationBaseObject, ISecretId, IUserProvidedAPIKey
|
||||
{
|
||||
private static readonly ILogger<EmbeddingProvider> LOGGER = Program.LOGGER_FACTORY.CreateLogger<EmbeddingProvider>();
|
||||
|
||||
@@ -97,6 +98,10 @@ public sealed record EmbeddingProvider(
|
||||
return false;
|
||||
}
|
||||
|
||||
var allowUserProvidedApiKey = false;
|
||||
if (table.TryGetValue("AllowUserProvidedAPIKey", out var allowUserProvidedApiKeyValue) && allowUserProvidedApiKeyValue.TryRead<bool>(out var allowUserProvidedApiKeyBool))
|
||||
allowUserProvidedApiKey = allowUserProvidedApiKeyBool;
|
||||
|
||||
provider = new EmbeddingProvider
|
||||
{
|
||||
Num = 0, // will be set later by the PluginConfigurationObject
|
||||
@@ -109,10 +114,18 @@ public sealed record EmbeddingProvider(
|
||||
EnterpriseConfigurationPluginId = configPluginId,
|
||||
Hostname = hostname,
|
||||
Host = host,
|
||||
AllowUserProvidedAPIKey = allowUserProvidedApiKey,
|
||||
};
|
||||
|
||||
// Handle encrypted API key if present:
|
||||
if (table.TryGetValue("APIKey", out var apiKeyValue) && apiKeyValue.TryRead<string>(out var apiKeyText) && !string.IsNullOrWhiteSpace(apiKeyText))
|
||||
// Handle an encrypted API key if present. When the user manages their own key for this
|
||||
// embedding provider, we must never enqueue an embedded key: doing so would overwrite the
|
||||
// user's key in the OS keyring on every configuration reload.
|
||||
if (allowUserProvidedApiKey)
|
||||
{
|
||||
if (table.TryGetValue("APIKey", out var ignoredApiKeyValue) && ignoredApiKeyValue.TryRead<string>(out var ignoredApiKeyText) && !string.IsNullOrWhiteSpace(ignoredApiKeyText))
|
||||
LOGGER.LogWarning($"The configured embedding provider {idx} sets both AllowUserProvidedAPIKey and an embedded APIKey. Ignoring the embedded key: the user manages their own key for this provider. (Plugin ID: {configPluginId})");
|
||||
}
|
||||
else if (table.TryGetValue("APIKey", out var apiKeyValue) && apiKeyValue.TryRead<string>(out var apiKeyText) && !string.IsNullOrWhiteSpace(apiKeyText))
|
||||
{
|
||||
if (!EnterpriseEncryption.IsEncrypted(apiKeyText))
|
||||
LOGGER.LogWarning($"The configured embedding provider {idx} contains a plaintext API key. Only encrypted API keys (starting with 'ENC:v1:') are supported. (Plugin ID: {configPluginId})");
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace AIStudio.Settings;
|
||||
/// <param name="IsSelfHosted">Whether the provider is self-hosted.</param>
|
||||
/// <param name="Hostname">The hostname of the provider. Useful for self-hosted providers.</param>
|
||||
/// <param name="Model">The LLM model to use for chat.</param>
|
||||
/// <param name="AllowUserProvidedAPIKey">When set by a configuration plugin, the user may set their own API key for this otherwise locked, enterprise-managed provider.</param>
|
||||
public sealed record Provider(
|
||||
uint Num,
|
||||
string Id,
|
||||
@@ -34,7 +35,8 @@ public sealed record Provider(
|
||||
Host Host = Host.NONE,
|
||||
HFInferenceProvider HFInferenceProvider = HFInferenceProvider.NONE,
|
||||
string AdditionalJsonApiParameters = "",
|
||||
ProviderCapabilityOverrides? CapabilityOverrides = null) : ConfigurationBaseObject, ISecretId
|
||||
ProviderCapabilityOverrides? CapabilityOverrides = null,
|
||||
bool AllowUserProvidedAPIKey = false) : ConfigurationBaseObject, ISecretId, IUserProvidedAPIKey
|
||||
{
|
||||
private static readonly ILogger<Provider> LOGGER = Program.LOGGER_FACTORY.CreateLogger<Provider>();
|
||||
|
||||
@@ -155,6 +157,10 @@ public sealed record Provider(
|
||||
|
||||
var capabilityOverrides = ProviderCapabilityOverrides.TryParseFromLuaTable(idx, table, configPluginId, LOGGER);
|
||||
|
||||
var allowUserProvidedApiKey = false;
|
||||
if (table.TryGetValue("AllowUserProvidedAPIKey", out var allowUserProvidedApiKeyValue) && allowUserProvidedApiKeyValue.TryRead<bool>(out var allowUserProvidedApiKeyBool))
|
||||
allowUserProvidedApiKey = allowUserProvidedApiKeyBool;
|
||||
|
||||
provider = new Provider
|
||||
{
|
||||
Num = 0, // will be set later by the PluginConfigurationObject
|
||||
@@ -170,10 +176,18 @@ public sealed record Provider(
|
||||
HFInferenceProvider = hfInferenceProvider,
|
||||
AdditionalJsonApiParameters = additionalJsonApiParameters,
|
||||
CapabilityOverrides = capabilityOverrides,
|
||||
AllowUserProvidedAPIKey = allowUserProvidedApiKey,
|
||||
};
|
||||
|
||||
// Handle encrypted API key if present:
|
||||
if (table.TryGetValue("APIKey", out var apiKeyValue) && apiKeyValue.TryRead<string>(out var apiKeyText) && !string.IsNullOrWhiteSpace(apiKeyText))
|
||||
// Handle an encrypted API key if present. When the user manages their own key for this
|
||||
// provider, we must never enqueue an embedded key: doing so would overwrite the user's
|
||||
// key in the OS keyring on every configuration reload.
|
||||
if (allowUserProvidedApiKey)
|
||||
{
|
||||
if (table.TryGetValue("APIKey", out var ignoredApiKeyValue) && ignoredApiKeyValue.TryRead<string>(out var ignoredApiKeyText) && !string.IsNullOrWhiteSpace(ignoredApiKeyText))
|
||||
LOGGER.LogWarning($"The configured provider {idx} sets both AllowUserProvidedAPIKey and an embedded APIKey. Ignoring the embedded key: the user manages their own key for this provider. (Plugin ID: {configPluginId})");
|
||||
}
|
||||
else if (table.TryGetValue("APIKey", out var apiKeyValue) && apiKeyValue.TryRead<string>(out var apiKeyText) && !string.IsNullOrWhiteSpace(apiKeyText))
|
||||
{
|
||||
if (!EnterpriseEncryption.IsEncrypted(apiKeyText))
|
||||
LOGGER.LogWarning($"The configured provider {idx} contains a plaintext API key. Only encrypted API keys (starting with 'ENC:v1:') are supported. (Plugin ID: {configPluginId})");
|
||||
|
||||
@@ -20,7 +20,8 @@ public sealed record TranscriptionProvider(
|
||||
bool IsEnterpriseConfiguration = false,
|
||||
Guid EnterpriseConfigurationPluginId = default,
|
||||
string Hostname = "http://localhost:1234",
|
||||
Host Host = Host.NONE) : ConfigurationBaseObject, ISecretId
|
||||
Host Host = Host.NONE,
|
||||
bool AllowUserProvidedAPIKey = false) : ConfigurationBaseObject, ISecretId, IUserProvidedAPIKey
|
||||
{
|
||||
private static readonly ILogger<TranscriptionProvider> LOGGER = Program.LOGGER_FACTORY.CreateLogger<TranscriptionProvider>();
|
||||
|
||||
@@ -97,6 +98,10 @@ public sealed record TranscriptionProvider(
|
||||
return false;
|
||||
}
|
||||
|
||||
var allowUserProvidedApiKey = false;
|
||||
if (table.TryGetValue("AllowUserProvidedAPIKey", out var allowUserProvidedApiKeyValue) && allowUserProvidedApiKeyValue.TryRead<bool>(out var allowUserProvidedApiKeyBool))
|
||||
allowUserProvidedApiKey = allowUserProvidedApiKeyBool;
|
||||
|
||||
provider = new TranscriptionProvider
|
||||
{
|
||||
Num = 0, // will be set later by the PluginConfigurationObject
|
||||
@@ -109,10 +114,18 @@ public sealed record TranscriptionProvider(
|
||||
EnterpriseConfigurationPluginId = configPluginId,
|
||||
Hostname = hostname,
|
||||
Host = host,
|
||||
AllowUserProvidedAPIKey = allowUserProvidedApiKey,
|
||||
};
|
||||
|
||||
// Handle encrypted API key if present:
|
||||
if (table.TryGetValue("APIKey", out var apiKeyValue) && apiKeyValue.TryRead<string>(out var apiKeyText) && !string.IsNullOrWhiteSpace(apiKeyText))
|
||||
// Handle an encrypted API key if present. When the user manages their own key for this
|
||||
// transcription provider, we must never enqueue an embedded key: doing so would overwrite
|
||||
// the user's key in the OS keyring on every configuration reload.
|
||||
if (allowUserProvidedApiKey)
|
||||
{
|
||||
if (table.TryGetValue("APIKey", out var ignoredApiKeyValue) && ignoredApiKeyValue.TryRead<string>(out var ignoredApiKeyText) && !string.IsNullOrWhiteSpace(ignoredApiKeyText))
|
||||
LOGGER.LogWarning($"The configured transcription provider {idx} sets both AllowUserProvidedAPIKey and an embedded APIKey. Ignoring the embedded key: the user manages their own key for this provider. (Plugin ID: {configPluginId})");
|
||||
}
|
||||
else if (table.TryGetValue("APIKey", out var apiKeyValue) && apiKeyValue.TryRead<string>(out var apiKeyText) && !string.IsNullOrWhiteSpace(apiKeyText))
|
||||
{
|
||||
if (!EnterpriseEncryption.IsEncrypted(apiKeyText))
|
||||
LOGGER.LogWarning($"The configured transcription provider {idx} contains a plaintext API key. Only encrypted API keys (starting with 'ENC:v1:') are supported. (Plugin ID: {configPluginId})");
|
||||
|
||||
Reference in new issue
Block a user