From 9f1e62fdbf4441beb39c40403b0a360502aad35e Mon Sep 17 00:00:00 2001 From: Erik Simon Date: Wed, 29 Jul 2026 07:59:05 +0200 Subject: [PATCH] Remove hardcoded secrets; source credentials from configuration The Telegram bot token was a const in AddChannels(), and the Mistral API key was baked into the embedded Provider.Mistral.toml resource. - Wire AddChannels() through the existing (previously unused) AddTelegramOptions(), which binds "Channels:Telegram" and validates on start. TelegramOptions is resolved from IOptions<> so TelegramAdapter and TelegramChannel are unchanged. - Ship the embedded provider defaults with an empty ApiKey. Ollama's placeholder is now a non-secret literal. - Re-apply AddEnvironmentVariables() last in AddLunaConfiguration() so env vars override the TOML sources; without this the embedded defaults would shadow injected credentials. Credentials are now supplied via Providers__Mistral__ApiKey and Channels__Telegram__BotToken, or via ~/.luna/providers/*.toml overrides. Co-Authored-By: Claude Opus 5 --- .../Extensions/ServiceCollectionExtensions.cs | 14 ++++++++------ .../Extensions/ConfigurationBuilderExtensions.cs | 5 +++++ Luna.Configuration/Luna.Configuration.csproj | 1 + .../Resources/Providers/Provider.Mistral.toml | 3 +-- .../Resources/Providers/Provider.Ollama.toml | 3 +-- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/Luna.Channels/Extensions/ServiceCollectionExtensions.cs b/Luna.Channels/Extensions/ServiceCollectionExtensions.cs index 696616f..13312b4 100644 --- a/Luna.Channels/Extensions/ServiceCollectionExtensions.cs +++ b/Luna.Channels/Extensions/ServiceCollectionExtensions.cs @@ -1,25 +1,27 @@ using Luna.Channels.Abstractions; using Luna.Channels.Telegram; using Luna.Configuration; +using Luna.Configuration.Extensions; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Telegram.Bot; namespace Luna.Channels.Extensions; public static class ServiceCollectionExtensions { - private const string TelegramBotToken = "REDACTED-TELEGRAM-BOT-TOKEN"; - extension(IServiceCollection services) { public IServiceCollection AddChannels() { services.AddSingleton(); - // Telegram - var telegramOptions = new TelegramOptions { BotToken = TelegramBotToken }; - services.AddSingleton(telegramOptions); - services.AddSingleton(_ => new TelegramBotClient(TelegramBotToken)); + // Telegram — BotToken is bound from configuration ("Channels:Telegram"), + // supplied via the Channels__Telegram__BotToken environment variable. + services.AddTelegramOptions(); + services.AddSingleton(provider => provider.GetRequiredService>().Value); + services.AddSingleton(provider => + new TelegramBotClient(provider.GetRequiredService().BotToken)); services.AddHostedService(); return services; diff --git a/Luna.Configuration/Extensions/ConfigurationBuilderExtensions.cs b/Luna.Configuration/Extensions/ConfigurationBuilderExtensions.cs index 65c6261..19ef417 100644 --- a/Luna.Configuration/Extensions/ConfigurationBuilderExtensions.cs +++ b/Luna.Configuration/Extensions/ConfigurationBuilderExtensions.cs @@ -34,6 +34,11 @@ public static class ConfigurationBuilderExtensions builder.Add(new ProviderOptionsConfigurationSource(searchPath)); } + // Re-applied last so environment variables take precedence over the TOML + // sources above. This is how secrets (API keys, bot tokens) are supplied — + // the embedded defaults ship with empty credentials. + builder.AddEnvironmentVariables(); + return builder; } } diff --git a/Luna.Configuration/Luna.Configuration.csproj b/Luna.Configuration/Luna.Configuration.csproj index 4cca5d5..1f59ade 100644 --- a/Luna.Configuration/Luna.Configuration.csproj +++ b/Luna.Configuration/Luna.Configuration.csproj @@ -7,6 +7,7 @@ + diff --git a/Luna.Configuration/Resources/Providers/Provider.Mistral.toml b/Luna.Configuration/Resources/Providers/Provider.Mistral.toml index 5a78412..79f516f 100644 --- a/Luna.Configuration/Resources/Providers/Provider.Mistral.toml +++ b/Luna.Configuration/Resources/Providers/Provider.Mistral.toml @@ -1,5 +1,4 @@ -ApiKey = "REDACTED-MISTRAL-API-KEY" +ApiKey = "" ApiUrl = "https://api.mistral.ai/v1/" Models = ["mistral-small-latest"] - diff --git a/Luna.Configuration/Resources/Providers/Provider.Ollama.toml b/Luna.Configuration/Resources/Providers/Provider.Ollama.toml index 4cb1a53..d9948b0 100644 --- a/Luna.Configuration/Resources/Providers/Provider.Ollama.toml +++ b/Luna.Configuration/Resources/Providers/Provider.Ollama.toml @@ -1,5 +1,4 @@ -ApiKey = "apfelkuchen" +ApiKey = "ollama" ApiUrl = "http://localhost:11434/" Models = ["mistral-nemo:12b"] -