feat(secrets): scaffold ZB.MOM.WW.Secrets.Replicator.Grpc + secrets_hub.v1 pull-only proto

Adds the third replicator sibling next to Replicator.SqlServer and
Replicator.AkkaDotNet: the central-hosted gRPC secrets hub. This commit is
scaffold only -- project, wire contract, solution wiring -- no service or
client implementation.

The proto mirrors exactly the read half of ISecretReplicationHub
(GetManifestAsync, GetManyAsync). ApplyReplicatedAsync is deliberately NOT
mirrored: in this topology every update originates at central and a site node
is a strict follower, so the narrow contract IS the enforcement -- with no
write RPC on the wire, a mis-wired or compromised site node has no way to push
a row into the hub regardless of what its authorization allows.

Messages are hand-written mirrors of StoredSecret and SecretManifestEntry
rather than serializations of the domain types, following the Akka
replicator's SecretRowDto precedent: the trust boundary stays structural, and
a field added to StoredSecret later cannot start crossing the network merely
by existing. Timestamps are ISO-8601 "O" strings (not google.protobuf.
Timestamp, which cannot round-trip a DateTimeOffset's offset) so a relayed row
is byte-identical to the one central holds; nullable .NET fields use proto3
explicit presence so null and empty string stay distinguishable.

Grpc 2.76.0 / Google.Protobuf 3.34.1 match what ScadaBridge, OtOpcUa and the
sibling ZB.MOM.WW.LocalDb libraries already resolve, so a consumer taking both
gets one Grpc rather than a downgrade warning.

Claude-Session: https://claude.ai/code/session_014WNM4vjoVksyyBraTXSZE1
This commit is contained in:
Joseph Doherty
2026-08-07 05:48:27 -04:00
parent ad7df925ae
commit 5fd7bf524a
4 changed files with 211 additions and 0 deletions
@@ -30,6 +30,17 @@
<PackageVersion Include="Akka.Remote" Version="1.5.62" />
<PackageVersion Include="Akka.TestKit.Xunit2" Version="1.5.62" />
<!-- gRPC secrets hub (ZB.MOM.WW.Secrets.Replicator.Grpc).
2.76.0 / 3.34.1 is the version the whole family already resolves — ScadaBridge and
OtOpcUa pin exactly these, and the sibling ZB.MOM.WW.LocalDb libraries floor them there.
A consumer taking the hub alongside LocalDb replication must not be pushed into a
downgrade warning or an unplanned Grpc bump just to adopt secret replication. -->
<PackageVersion Include="Google.Protobuf" Version="3.34.1" />
<PackageVersion Include="Grpc.AspNetCore" Version="2.76.0" />
<PackageVersion Include="Grpc.Core.Api" Version="2.76.0" />
<PackageVersion Include="Grpc.Net.Client" Version="2.76.0" />
<PackageVersion Include="Grpc.Tools" Version="2.76.0" />
<!-- 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