feat(secrets): source LDAP bind password via ${secret:ldap/mxgateway/bind}; drop plaintext defaults (G-4)

This commit is contained in:
Joseph Doherty
2026-07-16 10:40:07 -04:00
parent a2538039c0
commit b79e119ada
7 changed files with 113 additions and 11 deletions
@@ -1,4 +1,5 @@
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
namespace ZB.MOM.WW.MxGateway.Tests.TestSupport;
@@ -51,5 +52,37 @@ internal static class TestHostEnvironmentInitializer
"gateway-selfsigned.pfx");
Environment.SetEnvironmentVariable("MxGateway__Tls__SelfSignedCertPath", certPath);
}
// Host-building tests must not depend on a seeded secret store. The shipped appsettings.json
// sources the LDAP bind password from ${secret:ldap/mxgateway/bind}, which the pre-host
// expander in GatewayApplication.CreateBuilder resolves before the host is built; with no
// seeded store (as on CI) that resolution fails closed with SecretNotFoundException. Supplying
// the bind password as an environment override — the same supported way an operator can — makes
// config["MxGateway:Ldap:ServiceAccountPassword"] a plain literal (the env provider outranks the
// JSON provider), so the expander sees no ${secret:} prefix and skips it. No store/seed needed.
if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("MxGateway__Ldap__ServiceAccountPassword")))
{
Environment.SetEnvironmentVariable("MxGateway__Ldap__ServiceAccountPassword", "test-bind-password");
}
// The runtime AddZbSecrets registration still runs SqliteSecretsStoreMigrator.MigrateAsync on
// startup, which needs a valid master key and a writable store path. Point the store at a
// per-process temp file (not the test working dir) and supply a throwaway base64 32-byte key so
// migration succeeds without touching any real/shared secrets store.
if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("ZB_SECRETS_MASTER_KEY")))
{
Environment.SetEnvironmentVariable(
"ZB_SECRETS_MASTER_KEY",
Convert.ToBase64String(RandomNumberGenerator.GetBytes(32)));
}
if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("Secrets__SqlitePath")))
{
string secretsPath = Path.Combine(
Path.GetTempPath(),
$"mxgw-tests-{Environment.ProcessId}",
"secrets.db");
Environment.SetEnvironmentVariable("Secrets__SqlitePath", secretsPath);
}
}
}