chore(secrets): deprecate Replicator.Grpc — out of the build and pack (scadaproj#8)
Owner chose option (b). ZB.MOM.WW.Secrets.Replicator.Grpc has had no consumer
since ScadaBridge retired the gRPC secrets hub (2026-09-28); OtOpcUa never used it.
- removed the project and its test project from ZB.MOM.WW.Secrets.slnx, so the
family build/test and build/push.sh's `dotnet pack` skip it;
- csproj IsPackable=false (a direct pack of the project yields nothing);
- SecretsGrpcHubServerExtensions / SecretsGrpcHubClientExtensions [Obsolete];
- README, CHANGELOG (0.6.6 Deprecated), CLAUDE.md and clustered-secrets.md say so.
Source + tests stay in the tree and still build/run standalone (test csproj
suppresses CS0618): 200/200. Feed versions 0.4.1-0.6.3 are left for the owner
to unlist.
Also zeroes the solution's pre-existing warnings: CA1416 on two Unix-only
permission tests (guarded by Skip.IfNot, which the analyzer cannot see — now
[UnsupportedOSPlatform("windows")]) and two xUnit2031 Assert.Single(Where).
Build 0 warnings; tests 429 passed / 21 skipped / 0 failed; pack = 5 nupkgs.
Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV
This commit is contained in:
@@ -10,6 +10,18 @@ one of them.
|
||||
Fixes the scadaproj#15 code-review findings (`code-reviews/Secrets/findings.md`): six P2s (scadaproj#30–#35),
|
||||
the P3 batch (scadaproj#45: Secrets-004–009, 011, 012, 014–016, 018, 019) and the scadaproj#49 follow-ups.
|
||||
|
||||
### Deprecated
|
||||
|
||||
- **`ZB.MOM.WW.Secrets.Replicator.Grpc` is deprecated** (scadaproj#8, owner decision 2026-11-09). The
|
||||
pull-only `secrets_hub.v1` hub has had no consumer since ScadaBridge retired it (2026-09-28, site
|
||||
secrets now ride its artifact deploy); OtOpcUa never used it (Akka pair-local). The project and its
|
||||
test project are removed from `ZB.MOM.WW.Secrets.slnx`, so the family build, test run and pack
|
||||
(`build/push.sh`) no longer include it, and the csproj is `IsPackable=false`. `SecretsGrpcHubServerExtensions`
|
||||
(`AddZbSecretsGrpcHub`, `MapZbSecretsHub`) and `SecretsGrpcHubClientExtensions` (`AddZbSecretsGrpcHubClient`)
|
||||
are `[Obsolete]`. **No `0.6.6` of this package will be published**; `0.4.1`–`0.6.3` stay on the feed
|
||||
until the owner unlists them. Source and tests stay in the tree and still build standalone
|
||||
(`dotnet test tests/ZB.MOM.WW.Secrets.Replicator.Grpc.Tests`).
|
||||
|
||||
### scadaproj#52 follow-ups
|
||||
|
||||
- **The CLI reference audit reports malformed `${secret:}` tokens.** New `ReferenceStatus.Malformed`:
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# ZB.MOM.WW.Secrets
|
||||
|
||||
Shared encrypted secret store + `${secret:}` resolution for the **ZB.MOM.WW SCADA family** (5 packages + the `secret` CLI; replicators for SqlServer / AkkaDotNet / Grpc). Build/test from this directory: `dotnet test`. Component spec + gaps: `../components/secrets/`. Operator runbooks under `docs/operations/`.
|
||||
Shared encrypted secret store + `${secret:}` resolution for the **ZB.MOM.WW SCADA family** (5 packages + the `secret` CLI; replicators for SqlServer / AkkaDotNet; the Grpc replicator is deprecated — scadaproj#8). Build/test from this directory: `dotnet test`. Component spec + gaps: `../components/secrets/`. Operator runbooks under `docs/operations/`.
|
||||
|
||||
**Backlog / open work:** lives in Gitea issues on `dohertj2/scadaproj` (`tea issues list --repo dohertj2/scadaproj`) — currently #7 (ignitionoee router pins), #8 (Replicator.Grpc / `0.6.3` fate), #18 (migrator retry jitter). The history below is a record, not a status tracker; file new follow-ups as issues.
|
||||
**Backlog / open work:** lives in Gitea issues on `dohertj2/scadaproj` (`tea issues list --repo dohertj2/scadaproj`) — currently #7 (ignitionoee router pins), #18 (migrator retry jitter). The history below is a record, not a status tracker; file new follow-ups as issues.
|
||||
|
||||
**`ZB.MOM.WW.Secrets.Replicator.Grpc` — DEPRECATED (2026-11-09, scadaproj#8, owner chose option (b)):** removed from `ZB.MOM.WW.Secrets.slnx` together with its test project (so build/test/`build/push.sh` skip it), csproj `IsPackable=false`, both hub DI extension classes `[Obsolete]`; README/CHANGELOG/`docs/operations/clustered-secrets.md` say so. Source + tests stay in the tree and build standalone (the test csproj suppresses CS0618). No consumer: ScadaBridge retired the hub 2026-09-28, OtOpcUa never used it. Feed versions `0.4.1`–`0.6.3` are left for the owner to unlist.
|
||||
|
||||
**`0.6.6` — built, NOT published (2026-11-09, scadaproj#30–#35, #45, #49):** every scadaproj#15 review finding resolved (Secrets-001–019; 0 open) plus the #49 follow-ups (CLI default `SqlitePath`, plain-root reload gap documented) — see `CHANGELOG.md` and `../code-reviews/Secrets/findings.md`. Behaviour changes worth knowing before adopting: store paths through symlinks into the content root now fail validation, malformed `${secret:}` tokens fail startup, UI Reveal fails closed on audit failure.
|
||||
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
<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).
|
||||
<!-- gRPC secrets hub (ZB.MOM.WW.Secrets.Replicator.Grpc — DEPRECATED, scadaproj#8; outside the
|
||||
solution now, kept so the project still restores standalone).
|
||||
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
|
||||
|
||||
@@ -13,7 +13,7 @@ plaintext back on demand — from application code, from configuration, or from
|
||||
| `ZB.MOM.WW.Secrets.Ui` | Blazor RCL on `ZB.MOM.WW.Theme`: list / add / rotate / delete + policy-gated, audited reveal. |
|
||||
| `ZB.MOM.WW.Secrets.Replicator.SqlServer` | Cluster-wide secrets via SQL Server — as one shared store, or as a hub each node syncs against. |
|
||||
| `ZB.MOM.WW.Secrets.Replicator.AkkaDotNet` | Peer-to-peer replication over an Akka.NET cluster — partition-tolerant, no shared database. |
|
||||
| `ZB.MOM.WW.Secrets.Replicator.Grpc` | Central-hosted `secrets_hub.v1` gRPC hub, pull-only (sites sync from central; central never accepts a write over this channel) — for topologies where sites talk only to central, never a shared DB. |
|
||||
| ~~`ZB.MOM.WW.Secrets.Replicator.Grpc`~~ | **Deprecated (scadaproj#8, 0.6.6).** The central-hosted, pull-only `secrets_hub.v1` gRPC hub. It has had no consumer since ScadaBridge retired the hub (2026-09-28: site secrets ride its artifact deploy), so it is no longer built, tested or packed with the family and its entry points are `[Obsolete]`. The last published version is `0.6.3`; source stays under `src/` for reference. Use the SqlServer or Akka replicator instead. |
|
||||
|
||||
A `secret` CLI (`set` / `get` / `list` / `rm` / `rotate` / `rewrap-all`) ships in the repo (not packed).
|
||||
`set` and `rotate` take the value on **stdin** (`printf '%s' "$PW" | secret set db/pw -`) or, at a
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
<Project Path="src/ZB.MOM.WW.Secrets/ZB.MOM.WW.Secrets.csproj" />
|
||||
<Project Path="src/ZB.MOM.WW.Secrets.Replicator.SqlServer/ZB.MOM.WW.Secrets.Replicator.SqlServer.csproj" />
|
||||
<Project Path="src/ZB.MOM.WW.Secrets.Replicator.AkkaDotNet/ZB.MOM.WW.Secrets.Replicator.AkkaDotNet.csproj" />
|
||||
<Project Path="src/ZB.MOM.WW.Secrets.Replicator.Grpc/ZB.MOM.WW.Secrets.Replicator.Grpc.csproj" />
|
||||
<Project Path="src/ZB.MOM.WW.Secrets.Ui/ZB.MOM.WW.Secrets.Ui.csproj" />
|
||||
<Project Path="src/ZB.MOM.WW.Secrets.Cli/ZB.MOM.WW.Secrets.Cli.csproj" />
|
||||
</Folder>
|
||||
@@ -12,7 +11,6 @@
|
||||
<Project Path="tests/ZB.MOM.WW.Secrets.Tests/ZB.MOM.WW.Secrets.Tests.csproj" />
|
||||
<Project Path="tests/ZB.MOM.WW.Secrets.Replicator.SqlServer.Tests/ZB.MOM.WW.Secrets.Replicator.SqlServer.Tests.csproj" />
|
||||
<Project Path="tests/ZB.MOM.WW.Secrets.Replicator.AkkaDotNet.Tests/ZB.MOM.WW.Secrets.Replicator.AkkaDotNet.Tests.csproj" />
|
||||
<Project Path="tests/ZB.MOM.WW.Secrets.Replicator.Grpc.Tests/ZB.MOM.WW.Secrets.Replicator.Grpc.Tests.csproj" />
|
||||
<Project Path="tests/ZB.MOM.WW.Secrets.Ui.Tests/ZB.MOM.WW.Secrets.Ui.Tests.csproj" />
|
||||
</Folder>
|
||||
</Solution>
|
||||
|
||||
@@ -221,7 +221,11 @@ Which topology each app runs in production is decided — tracked as
|
||||
propagation proven with seeded isolation controls on the other pairs** rather than by mere
|
||||
absence. It supersedes the 2026-07-18 six-node gate as evidence, which predates the mesh
|
||||
Phase 6 partition.
|
||||
- **ScadaBridge: central gRPC hub (§2's SQL-hub mode is NOT used).** Site servers never talk to
|
||||
- **ScadaBridge: central gRPC hub (§2's SQL-hub mode is NOT used).** *Historical — superseded
|
||||
2026-09-28: ScadaBridge retired the gRPC hub (site secrets ride its artifact deploy), and the
|
||||
`ZB.MOM.WW.Secrets.Replicator.Grpc` package is **deprecated** as of family `0.6.6`
|
||||
(scadaproj#8: no longer built or packed; `0.6.3` is its last published version). The record below
|
||||
is kept for the gates it describes.* Site servers never talk to
|
||||
the DB directly — they talk to central for everything — so the SqlServer hub's site-side
|
||||
connection string violates the topology rule. The `ZB.MOM.WW.Secrets.Replicator.Grpc` package
|
||||
(central-hosted `secrets_hub.v1`, **pull-only: updates originate at central only, by design** —
|
||||
|
||||
+1
@@ -25,6 +25,7 @@ namespace ZB.MOM.WW.Secrets.Replicator.Grpc.DependencyInjection;
|
||||
/// the deployment topology rather than a setting that could be got wrong.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
[Obsolete("ZB.MOM.WW.Secrets.Replicator.Grpc is deprecated (scadaproj#8): it has no consumer since ScadaBridge retired the gRPC secrets hub (2026-09-28) and is no longer built, tested or packed. Use AddZbSecretsSqlServerStore, AddZbSecretsSqlServerReplication or AddZbSecretsAkkaReplication.")]
|
||||
public static class SecretsGrpcHubClientExtensions
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
+1
@@ -21,6 +21,7 @@ namespace ZB.MOM.WW.Secrets.Replicator.Grpc.DependencyInjection;
|
||||
/// <c>kek_id</c> mismatch, which reads like data corruption but is a deployment error.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
[Obsolete("ZB.MOM.WW.Secrets.Replicator.Grpc is deprecated (scadaproj#8): it has no consumer since ScadaBridge retired the gRPC secrets hub (2026-09-28) and is no longer built, tested or packed. Use AddZbSecretsSqlServerStore, AddZbSecretsSqlServerReplication or AddZbSecretsAkkaReplication.")]
|
||||
public static class SecretsGrpcHubServerExtensions
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
+7
-2
@@ -9,11 +9,16 @@
|
||||
<RootNamespace>ZB.MOM.WW.Secrets.Replicator.Grpc</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- DEPRECATED (scadaproj#8, owner decision 2026-11-09): no consumer since ScadaBridge retired
|
||||
the gRPC secrets hub (2026-09-28). Removed from ZB.MOM.WW.Secrets.slnx, so the family build,
|
||||
test run and `dotnet pack` (build/push.sh) no longer touch it; IsPackable=false keeps a
|
||||
direct `dotnet pack` of this project from producing a nupkg too. Source kept for reference
|
||||
and for the already-published 0.4.1–0.6.3 packages; feed unlisting is the owner's call. -->
|
||||
<PropertyGroup>
|
||||
<IsPackable>true</IsPackable>
|
||||
<IsPackable>false</IsPackable>
|
||||
<PackageId>ZB.MOM.WW.Secrets.Replicator.Grpc</PackageId>
|
||||
<Authors>ZB.MOM.WW</Authors>
|
||||
<Description>Central-hosted gRPC secrets hub (pull-only) for the ZB.MOM.WW SCADA family — site nodes follow central, ciphertext-only.</Description>
|
||||
<Description>DEPRECATED (scadaproj#8) — central-hosted gRPC secrets hub (pull-only) for the ZB.MOM.WW SCADA family — site nodes follow central, ciphertext-only.</Description>
|
||||
<PackageProjectUrl>https://gitea.dohertylan.com/dohertj2/scadaproj/src/branch/main/ZB.MOM.WW.Secrets</PackageProjectUrl>
|
||||
<RepositoryUrl>https://gitea.dohertylan.com/dohertj2/scadaproj</RepositoryUrl>
|
||||
</PropertyGroup>
|
||||
|
||||
+5
@@ -1,7 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<!-- Tests for the DEPRECATED Replicator.Grpc package (scadaproj#8). Removed from
|
||||
ZB.MOM.WW.Secrets.slnx with the package, so the family test run skips them; they still build
|
||||
and run standalone (`dotnet test tests/ZB.MOM.WW.Secrets.Replicator.Grpc.Tests`).
|
||||
CS0618: they exercise the [Obsolete] entry points on purpose. -->
|
||||
<PropertyGroup>
|
||||
<IsPackable>false</IsPackable>
|
||||
<NoWarn>$(NoWarn);CS0618</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
+2
@@ -233,6 +233,8 @@ public sealed class BundleFlowTests : IDisposable
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
// Skip.IfNot is invisible to CA1416; this states the platform guard the analyzer can see.
|
||||
[System.Runtime.Versioning.UnsupportedOSPlatform("windows")]
|
||||
public async Task Import_source_key_file_permission_denied_renders_friendly_error_without_importing()
|
||||
{
|
||||
Skip.IfNot(!OperatingSystem.IsWindows(), "Unix permission bits are exercised via UnixFileMode.");
|
||||
|
||||
+2
@@ -227,6 +227,8 @@ public sealed class KekDoctorFlowTests : IAsyncLifetime, IDisposable
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
// Skip.IfNot is invisible to CA1416; this states the platform guard the analyzer can see.
|
||||
[System.Runtime.Versioning.UnsupportedOSPlatform("windows")]
|
||||
public async Task File_old_key_source_permission_denied_renders_friendly_error_and_still_re_diagnoses()
|
||||
{
|
||||
Skip.IfNot(!OperatingSystem.IsWindows(), "Unix permission bits are exercised via UnixFileMode.");
|
||||
|
||||
+2
-2
@@ -214,8 +214,8 @@ public sealed class SecretsStorePathRulesTests
|
||||
services.AddZbSecrets(config, "Secrets");
|
||||
services.AddZbSecrets(config, "Secrets");
|
||||
|
||||
Assert.Single(services.Where(d => d.ServiceType == typeof(SecretsOptionsValidator)));
|
||||
Assert.Single(services.Where(d => d.ServiceType == typeof(IValidateOptions<SecretsOptions>)));
|
||||
Assert.Single(services, d => d.ServiceType == typeof(SecretsOptionsValidator));
|
||||
Assert.Single(services, d => d.ServiceType == typeof(IValidateOptions<SecretsOptions>));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
Reference in New Issue
Block a user