Files
scadaproj/ZB.MOM.WW.Secrets/Directory.Packages.props
T
Joseph Doherty dd0a846b64 feat(secrets): cluster replication via SQL Server and Akka.NET (G-7, 0.2.0)
Secrets were per-node SQLite, so a secret written on one node was invisible to
the rest of a cluster. G-7's design resolved the "shared SQL store vs Akka
replicator" fork to build only the former; both are built here so the choice is
a deployment decision (availability vs partition tolerance) rather than a
library limitation.

Two new packages — ZB.MOM.WW.Secrets.Replicator.SqlServer (shared store, plus a
local-store-with-hub mode) and .Replicator.AkkaDotNet (peer-to-peer over
distributed pub/sub). Core gains ISecretsStoreMigrator, one shared
SecretLastWriterWins predicate so no two stores can disagree on a tie, the
transport-agnostic reconciler, and ReplicatingSecretStore — which closes a real
gap: nothing had ever called ISecretReplicator.PublishAsync, so the seam was
inert and local writes would not have propagated at all.

Verified 182 pass / 1 skip / 0 warnings, including 15 live tests against a real
SQL Server 2022 (the SQLite suite ported case-for-case, so any behavioural
divergence between the stores fails) and a 9-test in-process 2-node Akka
cluster over real remoting. A post-build review caught six defects, all fixed
and now covered: both replication modes could not resolve from the container
(no test had built one), an unbounded fetch that broke past SQL Server's
2100-parameter cap, a poison row that aborted the rest of its batch forever,
Enum.Parse on peer input that could restart the actor in a loop, null crypto
blobs crossing the trust boundary, and a silently dropped pull-read failure.

Packed at 0.2.0 and vulnerability-scanned clean; not yet published to the feed.

Claude-Session: https://claude.ai/code/session_01BL2Vu1ESDQ9SCN4gVKkdts
2026-07-18 04:08:23 -04:00

70 lines
3.9 KiB
XML

<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<!-- Enable transitive pinning so the security override below (SQLitePCLRaw native lib) takes effect. -->
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
</PropertyGroup>
<ItemGroup>
<!-- LDAP -->
<PackageVersion Include="Novell.Directory.Ldap.NETStandard" Version="3.6.0" />
<!-- Data -->
<PackageVersion Include="Microsoft.Data.Sqlite" Version="10.0.7" />
<!-- Transitive security pin: Microsoft.Data.Sqlite 10.0.7 pulls SQLitePCLRaw.lib.e_sqlite3 2.1.11,
which carries advisory GHSA-2m69-gcr7-jv3q (NU1903). Pin the patched 2.1.12 native lib. -->
<PackageVersion Include="SQLitePCLRaw.lib.e_sqlite3" Version="2.1.12" />
<!-- Shared SQL-Server secret store (ZB.MOM.WW.Secrets.Replication.SqlServer).
6.0.2 matches the version ScadaBridge and ZB.MOM.WW.GalaxyRepository already resolve, so a
consumer taking both gets one SqlClient rather than a downgrade warning. -->
<PackageVersion Include="Microsoft.Data.SqlClient" Version="6.0.2" />
<!-- Akka cluster replication (ZB.MOM.WW.Secrets.Replication.Akka).
1.5.62 matches ScadaBridge's pinned Akka.NET line — the clustered consumer must not be
forced into an Akka version bump just to adopt secret replication. -->
<PackageVersion Include="Akka" Version="1.5.62" />
<PackageVersion Include="Akka.Cluster" Version="1.5.62" />
<PackageVersion Include="Akka.Cluster.Tools" Version="1.5.62" />
<PackageVersion Include="Akka.Remote" Version="1.5.62" />
<PackageVersion Include="Akka.TestKit.Xunit2" Version="1.5.62" />
<!-- Cryptography -->
<!-- 9.0.4, not 9.0.0: Microsoft.Data.SqlClient 6.0.2 pulls System.Configuration.ConfigurationManager
9.0.4, which requires ProtectedData >= 9.0.4. With transitive pinning on, the lower central
version is a hard NU1109 downgrade error rather than a silent resolve. -->
<PackageVersion Include="System.Security.Cryptography.ProtectedData" Version="9.0.4" />
<!-- Extensions -->
<PackageVersion Include="Microsoft.Extensions.Options" Version="10.0.7" />
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="10.0.7" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.7" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.7" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="10.0.7" />
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="10.0.7" />
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.7" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="10.0.7" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.7" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.7" />
<!-- ASP.NET Core Authentication / Authorization -->
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.7" />
<PackageVersion Include="Microsoft.AspNetCore.Authorization" Version="10.0.7" />
<!-- ZB.MOM.WW shared libraries (Gitea feed) -->
<PackageVersion Include="ZB.MOM.WW.Audit" Version="0.1.0" />
<PackageVersion Include="ZB.MOM.WW.Theme" Version="0.2.0" />
<PackageVersion Include="ZB.MOM.WW.Auth.AspNetCore" Version="0.1.4" />
<!-- Test -->
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.4" />
<PackageVersion Include="Xunit.SkippableFact" Version="1.5.61" />
<PackageVersion Include="coverlet.collector" Version="6.0.4" />
<PackageVersion Include="bunit" Version="1.40.0" />
</ItemGroup>
</Project>