[Secrets] AddZbSecrets before the SqlServer/hub extensions silently cancels the shared store / replicator #30
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
From the scadaproj#15 shared-library review (
code-reviews/Secrets/findings.md, Secrets-001), verified at91fb2b4. Update the finding's Resolution row when fixed.ZB.MOM.WW.Secrets/src/ZB.MOM.WW.Secrets.Replicator.SqlServer/DependencyInjection/SqlServerSecretsServiceCollectionExtensions.cs:53(also:54,:90)Description
Both SQL-Server modes put their registrations in with
TryAddSingleton, and they only take effect because they run before the extension's own internalAddZbSecretscall (:57,:94). If the application has already calledAddZbSecrets, the SQLiteISecretStore, the SQLiteISecretsStoreMigratorandNoOpSecretReplicatorare already registered. EveryTryAddthen does nothing:AddZbSecretsSqlServerStorechanges nothing at all.AddZbSecretsSqlServerReplicationstill decorates the store, but with the no-op replicator.There is no exception, no log line and no documentation of the order requirement. Calling
AddZbSecretsfirst is the natural order: it is the order the README teaches, and it is the order an application uses to passcontentRootPath(see Secrets-002).Failure scenario
The application calls
services.AddZbSecrets(cfg, "Secrets", contentRoot)and thenservices.AddZbSecretsSqlServerStore(cfg). The probe resolvedISecretStore = SqliteSecretStoreandISecretsStoreMigrator = SqliteSecretsStoreMigrator. Each node of the "shared-store" central pair therefore writes to its own local SQLite file. A secret set on node A is never visible on node B, and the hub database is never even migrated. In hub mode the probe resolvedISecretReplicator = NoOpSecretReplicator, so live publish is silently disabled and propagation waits for the sync interval.Recommendation
Make the SQL-Server extensions order-independent: use
Replace/RemoveAll+AddforISecretStore,ISecretsStoreMigratorandISecretReplicator, rather thanTryAdd. Alternatively, throw if a conflicting registration is already present. Add container tests for both orders.Resolution
Unresolved.
Fixed on main 4f069c1 (Secrets-001 → Resolved): the SqlServer and Akka extensions call AddZbSecrets themselves, then replace the store/migrator/replicator registrations instead of TryAdd-ing first — registration order no longer matters (before: AddZbSecrets first → SQLite store / NoOpSecretReplicator in hub and Akka modes). Applied to AddZbSecretsAkkaReplication too. Evidence: Secrets solution (5 test projects) all pass — Core 246 (1 DPAPI skip), SqlServer 60 (16 live-SQL skips), Akka 44, Grpc 196, Ui 20; each regression test fails with its fix removed. Ships in Secrets 0.6.6 (unpublished).