chore(secrets): 0.4.0 — ship ZB.MOM.WW.Secrets.Replicator.Grpc (pull-only central hub)
Bumps the ZB.MOM.WW.Secrets family from 0.3.0 to 0.4.0 and adds the new ZB.MOM.WW.Secrets.Replicator.Grpc package to the packable set. Publishes all six 0.4.0 nupkgs to the dohertj2-gitea feed and restore-verifies the new package resolves from it in a fresh --packages directory. Existing packages are behaviorally unchanged — no breaking changes. Adds ZB.MOM.WW.Secrets/CHANGELOG.md (none existed previously) to record this and prior releases, and lists the new package in README.md's Packages table. Also includes the controller's pending ledger updates for docs/plans/2026-08-07-secrets-grpc-hub-implementation.md (Tasks 1-4 and 8 marked completed). Claude-Session: https://claude.ai/code/session_014WNM4vjoVksyyBraTXSZE1
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to the `ZB.MOM.WW.Secrets` family are recorded here. Format loosely
|
||||
follows [Keep a Changelog](https://keepachangelog.com/); versions are shared across every
|
||||
package in the family (see `Directory.Build.props`) even when a given release only touches
|
||||
one of them.
|
||||
|
||||
## 0.4.0 — 2026-08-07
|
||||
|
||||
### Added
|
||||
|
||||
- **New package `ZB.MOM.WW.Secrets.Replicator.Grpc`** — a central-hosted `secrets_hub.v1`
|
||||
gRPC hub for the sites-talk-to-central production topology (scadaproj#3; design doc
|
||||
[`docs/plans/2026-08-07-secrets-production-topology-and-grpc-hub.md`](../docs/plans/2026-08-07-secrets-production-topology-and-grpc-hub.md)).
|
||||
- **Pull-only by construction**: the proto exposes no write RPC. Updates originate at
|
||||
central only; a site never pushes a secret upstream.
|
||||
- **Fail-closed bearer auth** on the hub server: constant-time comparison, uniform denial
|
||||
response (no signal distinguishing "wrong token" from "missing token"), a warn-once log
|
||||
on an unconfigured/empty token rather than a silent open door.
|
||||
- `GetSecrets` enforces a batch-size cap, rejecting an oversized request with
|
||||
`ResourceExhausted` instead of serving it partially or unbounded.
|
||||
- Site-side `GrpcSecretSyncService` sweeps the hub on an interval with **per-row parse
|
||||
isolation** — one malformed/undecryptable row logs and is skipped, it does not fault the
|
||||
whole sweep.
|
||||
- Keyed `GrpcChannel` registration so multiple hub targets can be wired in one process
|
||||
without channel collisions.
|
||||
- **Offline behavior is last-known-good**: if the hub is unreachable, the site keeps
|
||||
serving the most recently synced values rather than failing secret resolution.
|
||||
|
||||
### Unchanged
|
||||
|
||||
- `ZB.MOM.WW.Secrets.Abstractions`, `ZB.MOM.WW.Secrets`, `ZB.MOM.WW.Secrets.Ui`,
|
||||
`ZB.MOM.WW.Secrets.Replicator.SqlServer`, and `ZB.MOM.WW.Secrets.Replicator.AkkaDotNet` are
|
||||
behaviorally unchanged in this release — no breaking changes to any existing package.
|
||||
|
||||
## 0.3.0 — 2026-07-19
|
||||
|
||||
- Menu-driven Spectre.Console interactive operator console added to the `secret` CLI (list /
|
||||
set / reveal / delete, reference audit & seed, KEK doctor, ciphertext-only bundle
|
||||
export/import). See
|
||||
[`docs/operations/interactive-console.md`](docs/operations/interactive-console.md).
|
||||
|
||||
## 0.2.3 — 2026-07-19
|
||||
|
||||
- `ZB.MOM.WW.Secrets.Ui`: fixed the delete-confirmation modal being permanently invisible on
|
||||
every Bootstrap host (`ConfirmDeleteModal` used bare `class="modal"` with no shipped CSS;
|
||||
Bootstrap's `.modal{display:none}` hid it everywhere but mxaccessgw). Fixed via a
|
||||
`zb-secrets-modal*` class rename plus a component-emitted `<style>` block.
|
||||
|
||||
## 0.2.2 — 2026-07-18
|
||||
|
||||
- Fixed the Akka replicator's hosted-process DI deadlock (a circular singleton dependency
|
||||
hidden behind factory lambdas that MS.DI's `StackGuard` turned into a silent cross-thread
|
||||
hang rather than a stack overflow). New `DeferredSecretCacheInvalidator` defers the one
|
||||
cycle-closing edge to first eviction.
|
||||
|
||||
## 0.2.1 — 2026-07-18
|
||||
|
||||
- Fixed the Akka replicator being silently inert since 0.2.0 (a `TryAdd` registration-order
|
||||
bug published into a no-op sink and never spawned an actor). SQL-Server replication was
|
||||
never affected.
|
||||
|
||||
## 0.2.0 — 2026-07-18
|
||||
|
||||
- Added clustered replication (G-7): `ZB.MOM.WW.Secrets.Replicator.SqlServer` (shared store,
|
||||
or local-store-with-hub) and `ZB.MOM.WW.Secrets.Replicator.AkkaDotNet` (peer-to-peer over
|
||||
distributed pub/sub).
|
||||
@@ -5,7 +5,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Version>0.3.0</Version>
|
||||
<Version>0.4.0</Version>
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -13,6 +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. |
|
||||
|
||||
A `secret` CLI (`set` / `get` / `list` / `rm` / `rotate` / `rewrap-all`) ships in the repo (not packed).
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"planPath": "docs/plans/2026-08-07-secrets-grpc-hub-implementation.md",
|
||||
"tasks": [
|
||||
{"id": 1, "subject": "Task 1: Package scaffold + secrets_hub.v1 proto", "status": "pending", "classification": "standard", "parallelizableWith": [8]},
|
||||
{"id": 2, "subject": "Task 2: Server half — hub service + bearer auth + DI", "status": "pending", "classification": "high-risk", "blockedBy": [1], "parallelizableWith": [3]},
|
||||
{"id": 3, "subject": "Task 3: Client half — pull-only sweep service + DI", "status": "pending", "classification": "high-risk", "blockedBy": [1], "parallelizableWith": [2]},
|
||||
{"id": 4, "subject": "Task 4: Integration tests + no-write-surface pin", "status": "pending", "classification": "standard", "blockedBy": [2, 3]},
|
||||
{"id": 1, "subject": "Task 1: Package scaffold + secrets_hub.v1 proto", "status": "completed", "classification": "standard", "parallelizableWith": [8], "note": "5fd7bf5 + cf6d19d (evolution-policy header) + cc95590 (test project scaffold); spec ✅, code review Approved"},
|
||||
{"id": 2, "subject": "Task 2: Server half — hub service + bearer auth + DI", "status": "completed", "classification": "high-risk", "blockedBy": [1], "parallelizableWith": [3], "note": "7fc77f2 + 353af72 (review fixes: GetSecrets batch cap, DI single-registration guard) merged ff into feat/secrets-grpc-hub; spec ✅ 16/16, code review Approved; 73 server tests"},
|
||||
{"id": 3, "subject": "Task 3: Client half — pull-only sweep service + DI", "status": "completed", "classification": "high-risk", "blockedBy": [1], "parallelizableWith": [2], "note": "c5ea3a7 + 1c31e6b (review Critical fix: per-row parse isolation, WireToDomain batch methods deleted, real-client CallInvoker tests) merged 55e0178; spec ✅ 8/8, code review Approved on re-review; merged suite 140/140"},
|
||||
{"id": 4, "subject": "Task 4: Integration tests + no-write-surface pin", "status": "completed", "classification": "standard", "blockedBy": [2, 3], "note": "3e3748b + 5f81e65 (harness drift-fix via internal validateEagerly seam); spec ✅ 6/6, code review Approved; Grpc suite 158, solution 436/0/15"},
|
||||
{"id": 5, "subject": "Task 5: Version bump + pack + publish 0.4.0", "status": "pending", "classification": "small", "blockedBy": [4]},
|
||||
{"id": 6, "subject": "Task 6: ScadaBridge wiring — central hub + site sweep client", "status": "pending", "classification": "high-risk", "blockedBy": [5]},
|
||||
{"id": 7, "subject": "Task 7: ScadaBridge live gate (docker cluster)", "status": "pending", "classification": "high-risk", "blockedBy": [6], "parallelizableWith": [8]},
|
||||
{"id": 8, "subject": "Task 8: OtOpcUa Akka pair-local re-gate (three-mesh rig)", "status": "pending", "classification": "high-risk", "parallelizableWith": [1, 2, 3, 4, 5, 6, 7]},
|
||||
{"id": 8, "subject": "Task 8: OtOpcUa Akka pair-local re-gate (three-mesh rig)", "status": "completed", "classification": "high-risk", "parallelizableWith": [1, 2, 3, 4, 5, 6, 7], "note": "PASS 4/4, OtOpcUa master @ 1bd79c8e pushed; gate doc docs/plans/2026-08-07-secrets-pair-local-live-gate.md; rig fix: Secrets__SqlitePath onto per-node volume; follow-up for Task 9: stale KNOWN-NON-FUNCTIONAL comment in OtOpcUa appsettings.json Secrets block"},
|
||||
{"id": 9, "subject": "Task 9: Closeout — issue #3, runbook, GAPS, index", "status": "pending", "classification": "small", "blockedBy": [7, 8]}
|
||||
],
|
||||
"lastUpdated": "2026-08-07"
|
||||
|
||||
Reference in New Issue
Block a user