diff --git a/src/ZB.MOM.WW.ScadaBridge.Host/Program.cs b/src/ZB.MOM.WW.ScadaBridge.Host/Program.cs index ac8fbb24..2a6ac1a0 100644 --- a/src/ZB.MOM.WW.ScadaBridge.Host/Program.cs +++ b/src/ZB.MOM.WW.ScadaBridge.Host/Program.cs @@ -1,3 +1,4 @@ +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Options; using ZB.MOM.WW.Auth.ApiKeys.DependencyInjection; @@ -26,6 +27,10 @@ using ZB.MOM.WW.ScadaBridge.Security; using ZB.MOM.WW.ScadaBridge.SiteCallAudit; using ZB.MOM.WW.ScadaBridge.TemplateEngine; using ZB.MOM.WW.ScadaBridge.Transport; +using ZB.MOM.WW.Secrets.Abstractions; +using ZB.MOM.WW.Secrets.Configuration; +using ZB.MOM.WW.Secrets.DependencyInjection; +using ZB.MOM.WW.Secrets.Sqlite; using ZB.MOM.WW.Telemetry; using Serilog; @@ -42,6 +47,20 @@ var configuration = new ConfigurationBuilder() .AddCommandLine(args) .Build(); +// Expand ${secret:...} config references before any validator/binder sees them (Layer A). +// Throwaway provider — disposed here, shares no singletons with the host container. +#pragma warning disable ASP0000 // deliberate throwaway container +await using (var secretsProvider = new ServiceCollection() + .AddZbSecrets(configuration, "Secrets") + .BuildServiceProvider()) +#pragma warning restore ASP0000 +{ + await secretsProvider.GetRequiredService().MigrateAsync(default); + var resolver = secretsProvider.GetRequiredService(); + await new SecretReferenceExpander(resolver) + .ExpandConfigurationAsync(configuration, default); +} + // Full startup validation — fail fast before any DI or actor system setup StartupValidator.Validate(configuration); diff --git a/src/ZB.MOM.WW.ScadaBridge.Host/appsettings.json b/src/ZB.MOM.WW.ScadaBridge.Host/appsettings.json index 39500a48..d9041375 100644 --- a/src/ZB.MOM.WW.ScadaBridge.Host/appsettings.json +++ b/src/ZB.MOM.WW.ScadaBridge.Host/appsettings.json @@ -9,6 +9,12 @@ } } }, + "Secrets": { + "SqlitePath": "scadabridge-secrets.db", + "MasterKey": { "Source": "Environment", "EnvVarName": "ZB_SECRETS_MASTER_KEY" }, + "RunMigrationsOnStartup": true, + "ResolveCacheTtl": "00:00:30" + }, "Serilog": { "Using": [ "Serilog.Sinks.Console",