docs(#891): vd03 worker isolation + box-wide ApiInstall deny + backup lockdown
v2-ci / unit-tests (push) Has been cancelled

Claude-Session: https://claude.ai/code/session_01GT67ACmpMR7b9LGRPLijMi
This commit is contained in:
Joseph Doherty
2026-11-12 19:37:04 -05:00
parent f47891ff50
commit aaaa55e211
@@ -379,3 +379,31 @@ Run over WinRM (owner-authorised for this upgrade) with staged scripts; the buil
been re-pointed in the AdminUI and deployed as `9adc5590` (11:06:43 UTC, `/fleet` Applied, chip "In sync").
Client CLI reads: `…/Spindle/S1/MotorSpeedPct` Good (0, spindle idle), `…/Spindle/S1/Load` Good,
`…/Spindle/S1/MaxRpm` `BadNodeIdUnknown` as expected, and the UNS `parts-count`/`parts-required` still present.
## Worker isolation and box-wide denies (lmxopcua#891, 2026-11-12, owner-requested)
The vd03 layout differs from QA. The install root is `E:\ApiInstall\OtOpcUa`, with no `app\` folder, and data lives in `E:\ApiInstall\OtOpcUa-data`. Copies containing secrets are spread across `E:\ApiInstall`: env/registry backups, `kek.key` files, and old `pki\own\private` copies in about a dozen `OtOpcUa.bak*` folders. So the deny covers **all of `E:\ApiInstall`** instead of listing each app folder.
**Installer:** `E:\psrem-stage\otopcua-891-f47891ff\install`, master `f47891ff`. SHA256: `.ps1` `e0c11aea…41a3`, `.psm1` `f9425e4c…dfde`.
```powershell
.\Install-ScriptWorkerIsolation.ps1 -InstallRoot E:\ApiInstall\OtOpcUa -HostServiceAccount LocalSystem `
-DenyPaths E:\ApiInstall,E:\ApiInstall\OtOpcUa\pki,E:\ApiInstall\OtOpcUa-data,C:\ProgramData\ZB\kek,E:\psrem-stage
```
- **Order:** `-WhatIf`, then apply (12 steps changed), then a re-apply (12 steps unchanged).
- **What the record holds:** the folders in `-DenyPaths` (the installer drops the install root, because `InstallRootDeny` already covers it), the PE cache, worker read+execute on `script-worker\`, and the outbound firewall block.
- **`script-worker\` stays usable:** its explicit `(RX)` comes before the deny inherited from `E:\ApiInstall`.
- **`-ConfigureHostService` deliberately left out.** The vd03 runner is still `InProcess` (the default), so the host service environment is unchanged and no restart was needed. When the vd03 runner flip is scheduled, re-run with the same `-DenyPaths` **plus** `-ConfigureHostService`, then set `Scripting__Runner` and restart.
**Backups locked down:** 39 files under `E:\ApiInstall` and `E:\psrem-stage` now have a protected DACL that allows only SYSTEM and Administrators: `*.reg`, `*envbak*.txt` and `*envnames*.txt`. That covers OtOpcUa, HG, mxgw and the ScadaBridge deploy backups. None were deleted.
**Installer warnings checked:**
- The locked backups have protected DACLs by design.
- `kek.key` in `HistorianGateway\data`, `MxGateway\data`, `OtOpcUa-data` and `ScadaBridge` allows only SYSTEM (Read) and Administrators.
None of them grants anything to Everyone, Users or RESTRICTED.
**After:** `/health/ready` returns 200 for OtOpcUa `:9000`, Overview `:5320`, ScadaBridge `:8085`, mxgw `:5130` and HG `:5220`.
**Rollback:** `-Uninstall`, which removes the recorded denies, the anchor service, the firewall rule and the PE cache ACLs. To undo the lockdown on a backup file, run `icacls <file> /reset`.