docs: PROGRAM COMPLETE — Auth+Audit normalization adopted across all 3 repos (Phases 0-3); mark exit-gate (CLAUDE.md Auth/Audit rows + components/{auth,audit}/GAPS.md adopted, local-only/not-pushed); tasks #10/#30/#31 done
This commit is contained in:
@@ -120,12 +120,12 @@ each project's **code-verified current state**, and the **gaps** between. See
|
||||
|
||||
| Component | Status | Goal | Design | Implementation |
|
||||
|---|---|---|---|---|
|
||||
| Auth (login / identity / authz) | Built (lib `0.1.0`) | Shared `ZB.MOM.WW.Auth` lib | [`components/auth/`](components/auth/) | [`ZB.MOM.WW.Auth/`](ZB.MOM.WW.Auth/) |
|
||||
| Auth (login / identity / authz) | Adopted (lib `0.1.3`; all 3 apps, **local-only branches** `feat/adopt-zb-auth`) | Shared `ZB.MOM.WW.Auth` lib | [`components/auth/`](components/auth/) | [`ZB.MOM.WW.Auth/`](ZB.MOM.WW.Auth/) |
|
||||
| UI Theme (layout / tokens / components) | Built (lib `0.1.0`) | Shared `ZB.MOM.WW.Theme` RCL | [`components/ui-theme/`](components/ui-theme/) | [`ZB.MOM.WW.Theme/`](ZB.MOM.WW.Theme/) |
|
||||
| Health (readiness / liveness / active-node) | Built (lib `0.1.0`) | Shared `ZB.MOM.WW.Health` lib | [`components/health/`](components/health/) | [`ZB.MOM.WW.Health/`](ZB.MOM.WW.Health/) |
|
||||
| Observability (metrics / traces / logs) | Built (lib `0.1.0`) | Shared `ZB.MOM.WW.Telemetry` lib + `.Serilog` | [`components/observability/`](components/observability/) | [`ZB.MOM.WW.Telemetry/`](ZB.MOM.WW.Telemetry/) |
|
||||
| Config + validation (options / startup validation) | Adopted (lib `0.1.0`; all 3 apps, local) | Shared `ZB.MOM.WW.Configuration` lib | [`components/configuration/`](components/configuration/) | [`ZB.MOM.WW.Configuration/`](ZB.MOM.WW.Configuration/) |
|
||||
| Audit (event model + writer seam) | Built (lib `0.1.0`) | Shared `ZB.MOM.WW.Audit` lib | [`components/audit/`](components/audit/) | [`ZB.MOM.WW.Audit/`](ZB.MOM.WW.Audit/) |
|
||||
| Audit (event model + writer seam) | Adopted (lib `0.1.0`; all 3 apps, **local-only branches** `feat/adopt-zb-audit`) | Shared `ZB.MOM.WW.Audit` lib | [`components/audit/`](components/audit/) | [`ZB.MOM.WW.Audit/`](ZB.MOM.WW.Audit/) |
|
||||
|
||||
The auth component is fully populated: a normalized [`spec`](components/auth/spec/SPEC.md), a
|
||||
proposed [`shared-contract`](components/auth/shared-contract/ZB.MOM.WW.Auth.md), three
|
||||
@@ -137,7 +137,13 @@ The shared library is **built and lives in this repo** at [`ZB.MOM.WW.Auth/`](ZB
|
||||
(its own nested git repo; .NET 10; 4 packages — `Abstractions`, `Ldap`, `ApiKeys`, `AspNetCore`;
|
||||
172 tests; `dotnet pack` → 4 nupkgs @ 0.1.0). The implementation plan is at
|
||||
[`docs/plans/2026-06-01-zb-mom-ww-auth-shared-library.md`](docs/plans/2026-06-01-zb-mom-ww-auth-shared-library.md).
|
||||
**Not yet adopted** by the three apps — that's the follow-on tracked in [`components/auth/GAPS.md`](components/auth/GAPS.md) (#8).
|
||||
**Adopted across all three apps on 2026-06-02** (auth GAPS #1–#8) on each repo's **local-only** `feat/adopt-zb-auth`
|
||||
branch — committed + reviewed, **NOT merged to default and NOT pushed** to any remote. Cutover: shared `Auth.Ldap`,
|
||||
`Auth.ApiKeys` (ScadaBridge inbound fully re-architected to the keyId/Bearer model), `IGroupRoleMapper<TRole>` seam,
|
||||
`Transport`-enum config, canonical `ZbClaimTypes`/`ZbCookieDefaults`, unified dev base DN `dc=zb,dc=local`, and the
|
||||
canonical-six role vocabulary (with ScadaBridge's accepted auditor/admin SoD collapse). Consumer pins: OtOpcUa `0.1.1`,
|
||||
MxGateway `0.1.2`, ScadaBridge `0.1.3`. Per-repo detail in [`components/auth/GAPS.md`](components/auth/GAPS.md) +
|
||||
`docs/plans/2026-06-02-auth-audit-normalization*.md`.
|
||||
Build/test from `ZB.MOM.WW.Auth/`: `dotnet test`. Consumer matrix: OtOpcUa → Abstractions+Ldap+AspNetCore;
|
||||
MxAccessGateway & ScadaBridge → all four (ApiKeys not used by OtOpcUa).
|
||||
|
||||
@@ -231,10 +237,19 @@ principal. `IAuditRedactor` is aligned with Telemetry's `ILogRedactor` seam conv
|
||||
The shared library is **built and lives in this repo** at [`ZB.MOM.WW.Audit/`](ZB.MOM.WW.Audit/)
|
||||
(.NET 10; 1 package — `ZB.MOM.WW.Audit`; only non-BCL dependency `Microsoft.Extensions.DependencyInjection.Abstractions`;
|
||||
19 tests; `dotnet pack` → 1 nupkg @ 0.1.0). Repo: `https://gitea.dohertylan.com/dohertj2/zb-mom-ww-audit`.
|
||||
**Not yet adopted** by the three apps — that's the follow-on tracked in [`components/audit/GAPS.md`](components/audit/GAPS.md).
|
||||
**Adopted across all three apps on 2026-06-02** (audit GAPS #1–#6) on each repo's **local-only** `feat/adopt-zb-audit`
|
||||
branch (stacked on `feat/adopt-zb-auth`) — committed + reviewed, **NOT merged to default and NOT pushed**. Depth =
|
||||
**DEEP adopt** (the canonical 9-field `AuditEvent` is the record everywhere; domain fields ride in `DetailsJson`).
|
||||
OtOpcUa: canonical record + `AuditWriterActor : IAuditWriter` + `Outcome` column/migration + `ClusterAudit` fix.
|
||||
MxGateway: new canonical SQLite `audit_event` store + `IAuditWriter` + `IApiKeyAuditStore`→canonical adapter.
|
||||
**ScadaBridge: a full audit-subsystem re-architecture** (the program's largest task) — canonical record everywhere via a
|
||||
deterministic codec; site SQLite split into `audit_event` + an `audit_forward_state` forwarding sidecar; central
|
||||
partitioned `dbo.AuditLog` collapsed to 10 canonical cols + persisted computed cols (`CollapseAuditLogToCanonical`
|
||||
migration, MSSQL-verified). Phase 3 wires `Actor` from the Auth principal at authenticated emit sites (per-app
|
||||
`IAuditActorAccessor`). Per-repo detail in [`components/audit/GAPS.md`](components/audit/GAPS.md) +
|
||||
`docs/plans/2026-06-02-auth-audit-normalization-phase2-deep.md` + `…-scadabridge-audit-rearch.md`.
|
||||
Build/test from `ZB.MOM.WW.Audit/`: `dotnet test`. Consumer matrix: all three apps consume the single
|
||||
`ZB.MOM.WW.Audit` package (OtOpcUa, MxAccessGateway, ScadaBridge each map their own audit record/seam
|
||||
onto the canonical type at the emit boundary).
|
||||
`ZB.MOM.WW.Audit` package (OtOpcUa, MxAccessGateway, ScadaBridge — DEEP-adopted as the canonical record).
|
||||
|
||||
## Per-project primary commands
|
||||
|
||||
|
||||
@@ -3,10 +3,18 @@
|
||||
Divergence of each project from [`spec/SPEC.md`](spec/SPEC.md), and the ordered backlog to
|
||||
reach the shared `ZB.MOM.WW.Audit` library. Status legend: ⛔ gap · 🟡 partial · ✅ matches.
|
||||
|
||||
> **Adoption is deferred this round.** The library is being designed (shared contract in
|
||||
> [`shared-contract/ZB.MOM.WW.Audit.md`](shared-contract/ZB.MOM.WW.Audit.md)) but is not yet
|
||||
> wired into any app — exactly where `ZB.MOM.WW.Auth` and `ZB.MOM.WW.Theme` sit today.
|
||||
> The items below are the follow-on work; each lands as a separate PR per project.
|
||||
> **✅ ADOPTED 2026-06-02 (local-only) — DEEP.** The backlog (#1–#6) was implemented across all three apps on each repo's
|
||||
> **`feat/adopt-zb-audit`** branch (stacked on `feat/adopt-zb-auth`) — committed + spec/code-reviewed, **NOT merged to
|
||||
> default and NOT pushed**. The user chose **DEEP adopt**: the canonical 9-field `AuditEvent` is the record EVERYWHERE
|
||||
> (domain fields ride in `DetailsJson`), so the §1 "keep own record" framing below was superseded. OtOpcUa: canonical
|
||||
> record + `AuditWriterActor : IAuditWriter` + `Outcome` col/migration + `ClusterAudit` fix. MxGateway: canonical SQLite
|
||||
> `audit_event` store + `IAuditWriter` + `IApiKeyAuditStore`→canonical adapter. **ScadaBridge: a full audit-subsystem
|
||||
> re-architecture** (codec + site `audit_event`/`audit_forward_state` sidecar + central partitioned-table collapse to
|
||||
> 10 canonical + persisted computed cols, MSSQL-verified). §5 (Actor→Auth principal) wired via per-app
|
||||
> `IAuditActorAccessor` (Phase 3). The Task 2.0 gate found this doc's pre-adoption framing was partly stale (MxGateway's
|
||||
> store had moved into the lib; OtOpcUa's structured path was dormant; ScadaBridge's filter was typed to its own record).
|
||||
> Detail: `docs/plans/2026-06-02-auth-audit-normalization-phase2-deep.md` + `…-scadabridge-audit-rearch.md`. The
|
||||
> ⛔/🟡 cells below describe the PRE-adoption divergence (kept for history).
|
||||
|
||||
## Divergence vs spec
|
||||
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
Divergence of each project from [`spec/SPEC.md`](spec/SPEC.md), and the ordered backlog to
|
||||
reach the shared `ZB.MOM.WW.Auth` library. Status legend: ⛔ gap · 🟡 partial · ✅ matches.
|
||||
|
||||
> **✅ ADOPTED 2026-06-02 (local-only).** The full backlog (#1–#8) was implemented across all three apps on each repo's
|
||||
> **`feat/adopt-zb-auth`** branch — committed + spec/code-reviewed, **NOT merged to default and NOT pushed**. Shared
|
||||
> `Auth.Ldap` + `Auth.ApiKeys` (ScadaBridge inbound re-architected to keyId/Bearer), `IGroupRoleMapper<TRole>`,
|
||||
> `Transport`-enum config, canonical `ZbClaimTypes`/`ZbCookieDefaults`, unified dev base DN `dc=zb,dc=local`, and the
|
||||
> canonical-six roles (with ScadaBridge's accepted auditor/admin SoD collapse). Consumer pins: OtOpcUa `0.1.1`,
|
||||
> MxGateway `0.1.2`, ScadaBridge `0.1.3`. Detail: `docs/plans/2026-06-02-auth-audit-normalization*.md`. The ⛔/🟡 cells
|
||||
> below describe the PRE-adoption divergence (kept for history).
|
||||
|
||||
## Divergence vs spec
|
||||
|
||||
### §1 LDAP config schema
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
{"id": 7, "subject": "Phase 0 umbrella — publish + feed-map", "status": "completed", "blockedBy": [11, 12, 13, 14, 15, 16]},
|
||||
{"id": 8, "subject": "Phase 1 umbrella — adopt ZB.MOM.WW.Auth — COMPLETE (all of 1.0-1.7 across 3 repos, reviewed, local-only)", "status": "completed", "blockedBy": [7, 17, 18, 19, 20, 21, 22, 23, 24]},
|
||||
{"id": 9, "subject": "Phase 2 umbrella — adopt ZB.MOM.WW.Audit — COMPLETE (OtOpcUa 2.1/2.2, MxGateway 2.3, ScadaBridge 2.5 full re-arch C1-C7; all reviewed, local-only)", "status": "completed", "blockedBy": [7, 8, 25, 26, 27, 28, 29]},
|
||||
{"id": 10, "subject": "Phase 3 umbrella — wire Actor from Auth principal", "status": "pending", "blockedBy": [8, 9, 30, 31]},
|
||||
{"id": 10, "subject": "Phase 3 umbrella — wire Actor from Auth principal — COMPLETE (IAuditActorAccessor per app + emit-site wiring; all reviewed, local-only)", "status": "completed", "blockedBy": [8, 9, 30, 31]},
|
||||
|
||||
{"id": 11, "subject": "Task 0.1: Add push.sh for ZB.MOM.WW.Audit", "status": "completed", "blockedBy": []},
|
||||
{"id": 12, "subject": "Task 0.2: Build+test both libs green", "status": "completed", "blockedBy": []},
|
||||
@@ -29,8 +29,8 @@
|
||||
{"id": 28, "subject": "Task 2.3: MxGateway store→IAuditWriter adapter (#2,#6) [re-scoped high-risk] — DONE a5944bb+7ea8358 (canonical SQLite store+adapter; spec+code reviewed)", "status": "completed", "blockedBy": [25]},
|
||||
{"id": 29, "subject": "Task 2.5: ScadaBridge audit DEEP full-rearch to 9-col canonical (#3) [high-risk] — DONE C1-C7 (3d77dc0,adfb4d3/5aaf9e2,db707bb/c27b2c3,946d3e2/1737d15,68a6bd1,C6-subsumed,635461c/bc0e5bf); all spec+code reviewed, MSSQL-verified", "status": "completed", "blockedBy": [25]},
|
||||
|
||||
{"id": 30, "subject": "Task 3.1: Introduce IAuditActorAccessor seam", "status": "pending", "blockedBy": [9]},
|
||||
{"id": 31, "subject": "Task 3.2-3.4: Wire emit sites to Auth principal (#4)", "status": "pending", "blockedBy": [30]},
|
||||
{"id": 30, "subject": "Task 3.1: IAuditActorAccessor seam (per-app HTTP accessor) — DONE (OtOpcUa 075c0e6, MxGw 0859d47, SB b3de840)", "status": "completed", "blockedBy": [9]},
|
||||
{"id": 31, "subject": "Task 3.2-3.4: Wire emit sites to Auth principal (#4) — DONE (MxGw dashboard Actor=operator/Target=keyId; SB inbound Actor from principal w/ auth-fail-null; OtOpcUa seam forward-looking) — reviewed", "status": "completed", "blockedBy": [30]},
|
||||
|
||||
{"id": 32, "subject": "Task 1.3-L: Extend Auth.ApiKeys admin store (SetScopes/SetEnabled) -> lib 0.1.3 (PUBLISHED)", "status": "completed", "blockedBy": []},
|
||||
{"id": 33, "subject": "Task 1.3-C1: ScadaBridge re-pin 0.1.3 + IInboundApiKeyAdmin seam (additive) + baseline reds fixed", "status": "completed", "blockedBy": [32]},
|
||||
@@ -39,5 +39,5 @@
|
||||
{"id": 36, "subject": "Task 1.3-C4: TransportExport exclude API keys (methods-only)", "status": "completed", "blockedBy": [33, 35]},
|
||||
{"id": 37, "subject": "Task 1.3-C5 (=E): retire SQL Server ApiKey entity + EF migration + runbook", "status": "completed", "blockedBy": [34, 35, 36]}
|
||||
],
|
||||
"lastUpdated": "2026-06-02 (Phase 2 COMPLETE: OtOpcUa+MxGateway+ScadaBridge audit done; ScadaBridge was DEEP full-rearch C1-C7. Next = Phase 3 Actor->principal wiring, tasks #30/#31)"
|
||||
"lastUpdated": "2026-06-02 — PROGRAM COMPLETE (Phases 0-3 done across 3 repos: Auth + Audit normalized, Actor wired from principal). All local-only on feat/adopt-zb-auth + feat/adopt-zb-audit; NOTHING pushed/merged. Remaining = exit-gate doc updates + user merge/push decision."
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user