# Redundant LDAP test pair (primary + backup "DC") Two GLAuth containers on the **dev Mac** that simulate the NAM two-DC topology (`uswap-vdc-nam1`/`nam2`) for exercising `ZB.MOM.WW.Auth.Ldap` **0.2.x `FallbackServers` sticky failover**. Deliberately local — the shared `zb-shared-glauth` on `10.100.0.35:3893` serves every other dev stack and must never be stopped for a drill. | | container | host port | from a container | |---|---|---|---| | primary | `zb-ldap-primary` | `3893` | `host.docker.internal:3893` | | backup | `zb-ldap-backup` | `3894` | `host.docker.internal:3894` | Both mount the same `config.toml` — identical directory contents, like a real replicated pair. It is a copy of [`../glauth/config.toml`](../glauth/config.toml) with one difference: the serviceaccount password here is the well-known local value `serviceaccount123` (the shared instance's is rotated out-of-band, SEC-36). Same users otherwise (`multi-role`/`password`, etc.). ```bash docker compose up -d # start the pair ``` ## Consumer wiring (any of the four apps) ``` Ldap__Server: host.docker.internal # primary Ldap__Port: "3893" Ldap__FallbackServers__0: host.docker.internal:3894 Ldap__Transport: None Ldap__AllowInsecure: "true" ``` Wired consumers (both drilled PASS 2026-08-13): - `HistorianGateway/docker/docker-compose.yml` (Auth `0.2.1`, dashboard login enabled). Note its Production-env container needs `Serilog__WriteTo__0__Name: Console` or it logs **nothing** — the drill's failover lines would be invisible. - ScadaBridge docker rig (`docker/central-node-{a,b}/appsettings.Central.json`, commit `b71fbae3`) — this pair REPLACED the shared `10.100.0.35` GLAuth there, whose serviceaccount password rotation (SEC-36) had silently broken rig login. ScadaBridge's `AuthFlowTests` also target `localhost:3893` and pass 5/5 with the pair up (they skip when it is down). ## Failover drill (verified PASS 2026-08-13 against HistorianGateway) 1. login → served by primary, no warnings 2. `docker stop zb-ldap-primary` → login OK; app logs `WRN LDAP endpoint …:3893 failed system-side at connect` + `INF LDAP sticky preference moved to …:3894` 3. `docker start zb-ldap-primary` → login OK, **still served by the backup** (sticky by design — verified by bind counts: primary got zero new binds) 4. `docker stop zb-ldap-backup` → login OK; warn on `:3894`, sticky moves back to `:3893` The sticky preference lives in the app's singleton `LdapAuthService`, so an app restart resets it to the configured primary.