Files
scadaproj/docs/plans/2026-06-04-shared-glauth-standardization-design.md
T

142 lines
9.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Shared GLAuth Standardization — Design
> **Status:** IMPLEMENTED + verified 2026-06-04 (all 18 plan tasks). See `shared-glauth-on-35` memory.
> Plan: [`2026-06-04-shared-glauth-standardization.md`](2026-06-04-shared-glauth-standardization.md).
> **Scope:** dev/test only. Production stays on real corporate AD (out of scope).
## Goal
Consolidate the three sister projects (OtOpcUa, MxAccessGateway, ScadaBridge) onto **one shared
GLAuth dev directory** running on the shared Docker host **`10.100.0.35:3893`**, replacing the
three separate LDAP setups in use today. This is the natural endpoint of the Auth-component
normalization: all three already use the shared `ZB.MOM.WW.Auth.Ldap` library (search-then-bind)
and already default to the same base DN `dc=zb,dc=local`.
## Decisions (locked during brainstorming)
| Decision | Choice |
|---|---|
| Environments | **Dev/test only** (prod → real AD, untouched) |
| Consolidation depth | **Full** — every dev instance points at 35 |
| Transport | **Plaintext** (`Transport=None`, `AllowInsecure=true`) — trusted lab subnet |
| Source of truth | **`scadaproj/infra/glauth/`** (app-neutral, next to the other shared `ZB.MOM.WW.*` components) — Approach A |
## Architecture
```
scadaproj/infra/glauth/ ← single source of truth (git)
├── config.toml (merged dc=zb,dc=local directory)
├── docker-compose.yml (one `glauth` service, :3893)
└── README.md
│ deploy on 10.100.0.35: docker compose up -d
GLAuth @ 10.100.0.35:3893 · datastore=config · baseDN dc=zb,dc=local · ldaps=false
▲ ▲
plaintext bind │ (None + AllowInsecure) │
┌──────────────┴───────────┐ ┌─────────┴─────────────────────┐
Mac / OrbStack │ windev (10.100.0.48)
• ScadaBridge :9000/:9100 │ • MxGateway (MxAccessGw svc)
• OtOpcUa docker-dev │ • OtOpcUa (OtOpcUa svc)
(un-stubbed)
```
- One `glauth` container on `10.100.0.35:3893`, `datastore=config`, `baseDN=dc=zb,dc=local`, ldaps disabled.
- Every dev consumer: `Server=10.100.0.35`, `Port=3893`, `Transport=None`, `AllowInsecure=true`, `SearchBase=dc=zb,dc=local`.
- **Retired:** the `scadabridge-ldap` container (ScadaBridge `infra/docker-compose.yml`) and the windev-local glauth (`C:\publish\glauth`).
- **Consequences:** windev gains a runtime dependency on 35 for *new* logins (existing cookie sessions unaffected); deploying to 35 needs working access (see Prerequisites).
## The merged directory
One `dc=zb,dc=local` directory; group families partitioned into **non-overlapping gid ranges** (today
both existing GLAuth files reuse 55015505 — the collision to fix). **Each app maps only its own family
and ignores the rest**, so the families coexist with zero conflict.
**Groups**
| Family | Used by | Groups (gidnumber) |
|---|---|---|
| `SCADA-*` (55xx) | ScadaBridge roles (DB-mapped) | Admins 5501, Designers 5502, Deploy-All 5503, Deploy-SiteA 5504, Viewers 5505 |
| OPC-perm (560x) | OtOpcUa + MxGateway OPC-UA write model | ReadOnly 5601, WriteOperate 5602, WriteTune 5603, WriteConfigure 5604, AlarmAck 5605 |
| `Gw*` (561x) | MxGateway dashboard (config-mapped) | GwAdmin 5610, GwReader 5611 |
| `OtOpcUa-*` (57xx) | OtOpcUa AdminUI (DB-mapped) | Admins 5701, Designers 5702, Viewers 5703 |
`SCADA-*` keeps its canonical 55xx numbers (already deployed). The OPC/`Gw` groups move off the old
55015505/5510 into 56xx to clear the clash.
**Users** (all password `password`; uid ranges 50xx ScadaBridge / 51xx MxGateway / 52xx OtOpcUa)
- **`serviceaccount`** (5999, `cn=serviceaccount,dc=zb,dc=local`, `search *` capability) — the *single*
bind account every app uses. Password `serviceaccount123`. ScadaBridge moves to it from `cn=admin`/`password`.
- **`multi-role`** (5005) — member of **every** group → all roles in all three apps (canonical cross-app QA login).
- **`admin`** (5001) — `SCADA-Admins` + `GwAdmin` + `OtOpcUa-Admins` → Administrator everywhere.
- Per-role testers: `designer`/`deployer`/`site-deployer` (ScadaBridge); `gwreader` (MxGateway Viewer);
`otdesigner`/`otviewer` (OtOpcUa); `readonly`/`writeop`/`writetune`/`writeconfig`/`alarmack` (OPC perms).
## Per-app config changes
Each consumer changes only its LDAP `Server` (+ a few keys). Shared service account
`cn=serviceaccount,dc=zb,dc=local` / `serviceaccount123`.
- **ScadaBridge** (`docker/` + `docker-env2/`, central-node-a & -b `appsettings.Central.json`):
`Ldap:Server` `scadabridge-ldap``10.100.0.35`; `ServiceAccountDn` `cn=admin``cn=serviceaccount`,
`ServiceAccountPassword``serviceaccount123`. Rest unchanged (`SCADA-*` DB mappings already seeded).
Retire the `ldap` service in `infra/docker-compose.yml`; sequenced-recreate central nodes.
- **OtOpcUa docker-dev** (`docker-dev/docker-compose.yml`, all host containers) — **the un-stub**:
drop `Security__Ldap__DevStubMode=true`; add `Server=10.100.0.35`, `Port=3893`, `Transport=None`,
`AllowInsecure=true`, `SearchBase=dc=zb,dc=local`, `ServiceAccountDn=cn=serviceaccount,…`,
`ServiceAccountPassword=serviceaccount123`. Seed OtOpcUa DB mappings
`OtOpcUa-Admins→Administrator`, `OtOpcUa-Designers→Designer`, `OtOpcUa-Viewers→Viewer` (system-wide).
- **MxGateway** (windev `C:\publish\mxaccessgw\Server\appsettings.json`): `Ldap:Server`
`localhost``10.100.0.35`; `SearchBase` `dc=lmxopcua``dc=zb,dc=local`; `ServiceAccountDn``…dc=zb,dc=local`.
`Transport=None`/`AllowInsecure=true` already migrated; `GroupToRole` (`GwAdmin`/`GwReader`) unchanged.
Restart `MxAccessGw` (+ dependent `OtOpcUa` svc).
- **OtOpcUa (windev service)**: locate its deployed overlay; repoint `Server``10.100.0.35`,
`SearchBase``dc=zb,dc=local`, service account, and switch dev transport `Ldaps``None`+`AllowInsecure`.
- **Then** stop/disable the windev-local `glauth` service.
## Rollout & rollback
Incremental; **the old glauths stay up until the very end**, so every step is reversible by pointing
`Server` back.
1. Stand up the shared glauth on 35 → verify via `ldapsearch` (bind `serviceaccount`; `multi-role`
`memberOf` spans all families). Nothing repointed yet.
2. Prove reachability from an OrbStack container to `10.100.0.35:3893` (the linchpin) before any app edit.
3. ScadaBridge `:9000` → recreate → browser-verify `multi-role` = 4 roles. Then `:9100`.
4. OtOpcUa docker-dev → un-stub + repoint + seed → recreate → verify.
5. windev MxGateway (backup appsettings) → restart → verify. Then windev OtOpcUa overlay.
6. Only once all green: stop/disable `scadabridge-ldap` + the windev-local glauth.
**Rollback** per consumer: revert the one-line `Server` change (git revert on the Mac; `.bak` restore on
windev) and recreate/restart. Remove the shared glauth = `docker compose down` on 35.
## Testing & verification
- **LDAP layer:** `ldapsearch` bind `serviceaccount`; confirm each test user + `multi-role`'s `memberOf`
across all four families; bind each user to confirm `password`.
- **Per-app browser (macbook Chrome):** ScadaBridge `:9000`/`:9100` `multi-role` → 4 roles (via
`/auth/token`); OtOpcUa `:9200` → seeded roles; MxGateway `10.100.0.48:5130` → Administrator; windev OtOpcUa → AdminUI.
- **Role-gating spot-checks:** `gwreader`→MxGateway Viewer-only; `designer`→ScadaBridge design-only;
`otviewer`→OtOpcUa read-only.
- **Negative:** wrong password rejected everywhere; a user in no family of an app → denied there.
## Prerequisites & open items (resolve in the plan)
1. **Access to `10.100.0.35`** — SSH from this Mac is currently refused (`Permission denied`/connection
reset) and the windev→35 jump is administratively prohibited. Either re-authorize this Mac's key on 35,
or the user runs the final `docker compose up -d`. Artifacts are portable either way.
2. **OtOpcUa group key shape** — confirm OtOpcUa maps on the **short RDN** (`OtOpcUa-Admins`) the shared
lib returns vs the full-DN its `LdapGroupRoleMapping` entity comment shows, before seeding.
3. **OrbStack→LAN reachability** — verify ScadaBridge/OtOpcUa containers can reach `10.100.0.35:3893`
early (likely fine; it's the linchpin). `log()` if any consumer can't reach 35 rather than silently failing.
4. **windev OtOpcUa config path** — discovery step (less is known about this deployment than MxGateway).
## Notes
- `scadaproj` is a plain-files umbrella that is *also* a local git repo; `infra/glauth/` lives here as the
canonical source. Per-app config edits land on a `feat/*` branch per repo (merge on the user's go).
windev edits are deployment-only with `.bak` backups (like the GroupToRole / LDAP-key migrations done
2026-06-04); repo templates optionally aligned.
- Related memory: `multi-role-cross-app-test-user`, `mxgateway-windev-deploy`,
`scadabridge-local-deploy-gotchas`, `auth-audit-normalization-in-progress`.