From a4f9968917cb03efd757cf6391dc8a7712043660 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Tue, 2 Jun 2026 03:14:29 -0400 Subject: [PATCH] plan(phase1): Auth lib 0.1.3 published (SetScopes/SetEnabled); ScadaBridge re-arch C mapping --- ...6-06-02-auth-audit-normalization-phase1.md | 12 ++++++++- ...-02-auth-audit-normalization.md.tasks.json | 26 +++++++++---------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/docs/plans/2026-06-02-auth-audit-normalization-phase1.md b/docs/plans/2026-06-02-auth-audit-normalization-phase1.md index 010fa2e..7792130 100644 --- a/docs/plans/2026-06-02-auth-audit-normalization-phase1.md +++ b/docs/plans/2026-06-02-auth-audit-normalization-phase1.md @@ -181,8 +181,18 @@ keeps the build green at each step. oracle), fail-fast pepper preflight (Central), audit actor = DisplayName. Old SQL Server path still compiles (retired in E). 163/163 InboundAPI tests green. **NOTE for E:** the library's `ApiKeySecretGenerator.NewSecret()` is `internal` — seed/create keys via the public `ApiKeyAdminCommands.CreateKeyAsync` seam (returns the assembled `sbk_…` token). +- **Library 0.1.3 — DONE + reviewed + PUBLISHED** (scadaproj commits `468959c` impl, `290e85c` tests; pushed to Gitea, + ApiKeys 0.1.3 nupkg verified HTTP 200). Added `IApiKeyAdminStore.SetScopesAsync(keyId, scopes, ct)` + `SetEnabledAsync(keyId, + enabled, whenUtc, ct)` (+ audited facade verbs `ApiKeyAdminCommands.SetScopesAsync`/`SetEnabledAsync` → eventTypes + `set-scopes`/`enable-key`/`disable-key`). **No schema change** (`CurrentVersion` stays 2): scopes column already exists; + `revoked_utc` doubles as the enabled flag (null = enabled), so enable/disable is a reversible toggle that preserves the + secret (proven by test asserting `SecretHash.SequenceEqual` + unchanged `last_used_utc`). This is what lets C/D edit a key's + method-scopes and toggle enabled WITHOUT re-issuing the token. **ScadaBridge must re-pin Auth packages 0.1.2 → 0.1.3.** - **C (management), D (CentralUI), E (retire SQL Server ApiKey + ApiMethod.ApprovedApiKeyIds migration + runbook/CHANGELOG) - — PENDING.** + — IN PROGRESS (C next).** Mapping for C: `CreateApiKeyCommand` → `CreateKeyAsync` (keyId = `Guid.NewGuid().ToString("N")`, + DisplayName = name, scopes = `--methods`); `ListApiKeysCommand` → `ListKeysAsync` (enabled = `RevokedUtc is null`); + `UpdateApiKeyCommand(IsEnabled)` → `SetEnabledAsync`; new set-scopes path → `SetScopesAsync`; `DeleteApiKeyCommand` → + revoke-then-`DeleteKeyAsync`. All management message keys switch `int ApiKeyId` → `string KeyId`. ## Resolved decisions (2026-06-02) diff --git a/docs/plans/2026-06-02-auth-audit-normalization.md.tasks.json b/docs/plans/2026-06-02-auth-audit-normalization.md.tasks.json index 6a3a10d..9d99ff2 100644 --- a/docs/plans/2026-06-02-auth-audit-normalization.md.tasks.json +++ b/docs/plans/2026-06-02-auth-audit-normalization.md.tasks.json @@ -2,23 +2,23 @@ "planPath": "docs/plans/2026-06-02-auth-audit-normalization.md", "designPath": "docs/plans/2026-06-02-auth-audit-normalization-design.md", "tasks": [ - {"id": 7, "subject": "Phase 0 umbrella — publish + feed-map", "status": "pending", "blockedBy": [11, 12, 13, 14, 15, 16]}, - {"id": 8, "subject": "Phase 1 umbrella — adopt ZB.MOM.WW.Auth", "status": "pending", "blockedBy": [7, 17, 18, 19, 20, 21, 22, 23, 24]}, + {"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", "status": "in_progress", "blockedBy": [7, 17, 18, 19, 20, 21, 22, 23, 24]}, {"id": 9, "subject": "Phase 2 umbrella — adopt ZB.MOM.WW.Audit", "status": "pending", "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": 11, "subject": "Task 0.1: Add push.sh for ZB.MOM.WW.Audit", "status": "pending", "blockedBy": []}, - {"id": 12, "subject": "Task 0.2: Build+test both libs green", "status": "pending", "blockedBy": []}, - {"id": 13, "subject": "Task 0.3: Pack+push both libs; verify HTTP 200", "status": "pending", "blockedBy": [11, 12]}, - {"id": 14, "subject": "Task 0.4: Feed-map + restore OtOpcUa", "status": "pending", "blockedBy": [13]}, - {"id": 15, "subject": "Task 0.5: Feed-map MxAccessGateway", "status": "pending", "blockedBy": [13]}, - {"id": 16, "subject": "Task 0.6: Feed-map + restore ScadaBridge", "status": "pending", "blockedBy": [13]}, + {"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": []}, + {"id": 13, "subject": "Task 0.3: Pack+push both libs; verify HTTP 200", "status": "completed", "blockedBy": [11, 12]}, + {"id": 14, "subject": "Task 0.4: Feed-map + restore OtOpcUa", "status": "completed", "blockedBy": [13]}, + {"id": 15, "subject": "Task 0.5: Feed-map MxAccessGateway", "status": "completed", "blockedBy": [13]}, + {"id": 16, "subject": "Task 0.6: Feed-map + restore ScadaBridge", "status": "completed", "blockedBy": [13]}, - {"id": 17, "subject": "Task 1.0: GATE explore auth source + elaborate", "status": "pending", "blockedBy": [14, 15, 16]}, - {"id": 18, "subject": "Task 1.1: IGroupRoleMapper seam (#3)", "status": "pending", "blockedBy": [17]}, - {"id": 19, "subject": "Task 1.2: Adopt Auth.Ldap cutover (#1) [high-risk]", "status": "pending", "blockedBy": [18]}, - {"id": 20, "subject": "Task 1.3: Adopt Auth.ApiKeys (#2) [high-risk]", "status": "pending", "blockedBy": [18]}, - {"id": 21, "subject": "Task 1.4: Config schema migration A1/A2 (#4)", "status": "pending", "blockedBy": [17]}, + {"id": 17, "subject": "Task 1.0: GATE explore auth source + elaborate", "status": "completed", "blockedBy": [14, 15, 16]}, + {"id": 18, "subject": "Task 1.1: IGroupRoleMapper seam (#3)", "status": "completed", "blockedBy": [17]}, + {"id": 19, "subject": "Task 1.2: Adopt Auth.Ldap cutover (#1) [high-risk]", "status": "completed", "blockedBy": [18]}, + {"id": 20, "subject": "Task 1.3: Adopt Auth.ApiKeys (#2) [high-risk] — MxGw done; ScadaBridge A+B done; C/D/E pending", "status": "in_progress", "blockedBy": [18]}, + {"id": 21, "subject": "Task 1.4: Config schema migration A1/A2 (#4)", "status": "completed", "blockedBy": [17]}, {"id": 22, "subject": "Task 1.5: AspNetCore claims/cookies (#5)", "status": "pending", "blockedBy": [17]}, {"id": 23, "subject": "Task 1.6: Unify dev base DN (#6)", "status": "pending", "blockedBy": [17]}, {"id": 24, "subject": "Task 1.7: Canonical roles native expansion (#8) [high-risk]", "status": "pending", "blockedBy": [18]},