docs(security): record the stage 6 live gate — PASSED on docker-dev

site-a-1 (driver-only, no ConfigDb) with Security:Acl:Enabled=true; central-1
on the same artifact as the A/B control. 11 legs.

The two that only a live rig could settle, as a transcript:

  13:49:39  SiteAOnly = 53   (0x00000000)   streaming ~1/s
  13:49:40  SiteAOnly =      (0x801F0000)   revoking deploy lands; client TOLD
            … 25 seconds of silence, ~25 updates that never arrived …
  13:50:05  SiteAOnly = 157  (0x00000000)   restoring deploy; feed resumes

53 -> 157 across the gap: the device counter ran throughout, so delivery
stopped, not the source. The 0x801F0000 frame is exactly what the
MonitoringMode.Disabled implementation would have swallowed.

Also recorded: the leg that distinguishes working enforcement from a trie that
denies everything is resolvedScopes=1 in the install log, not any denial.

Stated plainly as NOT covered: a UNS-realm grant (the rig's SITE-A has no UNS
equipment) and alarm-command scoping (no alarms there). Both covered offline,
neither seen live.

Two rig facts worth keeping: :9200 round-robins central-1/central-2, and a
stale central-2 rejected the deploy outright because its image predated the
stage-3 scope kinds — image parity must be asserted per container, not assumed
from one build. And SITEA-modbus had an empty DriverConfig, so it ran as a stub
serving nothing; until that was fixed every read returned
BadWaitingForInitialData and no allow leg could be told from a denial.

Rig left as found.

Claude-Session: https://claude.ai/code/session_015p7wGqy3YpZNCpDzTpGMKo
This commit is contained in:
Joseph Doherty
2026-08-01 09:52:42 -04:00
parent 2aa42f90eb
commit c4f537a60c
2 changed files with 57 additions and 8 deletions
+6
View File
@@ -320,6 +320,12 @@ takes no realm and no node.
|---|---|---|
| `Security:Acl:Enabled` | `false` | `true` makes scoped `NodeAcl` grants decide **every** data-plane operation — read, browse, subscribe, write, alarm commands and HistoryRead |
**Live-gated on docker-dev 2026-08-01** (site-a-1 with the flag on, central-1 as the same-artifact
control): scoped read/browse/write behave as described below, and revoking a grant stopped a running
subscription mid-stream — the client received `BadUserAccessDenied`, then 25 seconds of silence, then
the feed resumed by itself when the grant was restored. Evidence + what the gate did *not* cover (UNS
grants, alarm scoping) in `docs/plans/2026-07-31-apikey-acl-enforcement-design.md`.
**It is a config change, not a redeploy.** Both paths are wired in both modes — the node always builds
its permission trie on every deploy and always constructs the gate; the flag only chooses which decision
the seams consult. Same dark-switch discipline as `MeshTransport`, `ConfigSource` and `Telemetry`.