feat(secrets): pre-host ${secret:} config expander (ScadaBridge G-4 T2)

This commit is contained in:
Joseph Doherty
2026-07-16 14:13:53 -04:00
parent 481d6d7265
commit ae62e650e9
2 changed files with 25 additions and 0 deletions
+19
View File
@@ -1,3 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using ZB.MOM.WW.Auth.ApiKeys.DependencyInjection; 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.SiteCallAudit;
using ZB.MOM.WW.ScadaBridge.TemplateEngine; using ZB.MOM.WW.ScadaBridge.TemplateEngine;
using ZB.MOM.WW.ScadaBridge.Transport; 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 ZB.MOM.WW.Telemetry;
using Serilog; using Serilog;
@@ -42,6 +47,20 @@ var configuration = new ConfigurationBuilder()
.AddCommandLine(args) .AddCommandLine(args)
.Build(); .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<SqliteSecretsStoreMigrator>().MigrateAsync(default);
var resolver = secretsProvider.GetRequiredService<ISecretResolver>();
await new SecretReferenceExpander(resolver)
.ExpandConfigurationAsync(configuration, default);
}
// Full startup validation — fail fast before any DI or actor system setup // Full startup validation — fail fast before any DI or actor system setup
StartupValidator.Validate(configuration); StartupValidator.Validate(configuration);
@@ -9,6 +9,12 @@
} }
} }
}, },
"Secrets": {
"SqlitePath": "scadabridge-secrets.db",
"MasterKey": { "Source": "Environment", "EnvVarName": "ZB_SECRETS_MASTER_KEY" },
"RunMigrationsOnStartup": true,
"ResolveCacheTtl": "00:00:30"
},
"Serilog": { "Serilog": {
"Using": [ "Using": [
"Serilog.Sinks.Console", "Serilog.Sinks.Console",