feat(scripts): read-only, allow-listed Files global for site scripts; Delmia test receiver parses recipe files
Script file access (design docs/plans/2026-09-28-script-file-access-design.md): Files.ReadTextAsync / ReadLinesAsync / ExistsAsync on site ScriptGlobals (+ Instance.Files), backed by the site-singleton ScriptFileReader. The one host-mediated exception to the System.IO ban - scripts still never name a System.IO type. OFF by default: ScadaBridge:SiteRuntime:ScriptFileAccess:AllowedRoots (empty = every call throws Disabled) + MaxFileBytes (1 MiB, validated 1..64 MiB, roots must be absolute). Guard: fully qualified, no device paths / ADS, canonical path strictly inside a root (directory-boundary match), no reparse point on the file or any directory below the root, size cap before and during the read. Errors are one Commons type, ScriptFileAccessException(+ScriptFileAccessFailure); Commons.Types.Scripts joins the default script imports on every surface so it binds by short name. Mirrored on ScriptCompileSurface (CompileFiles, parity-pinned) and the Test Run sandbox (binds, refuses Disabled). Inbound (central) scripts do not get it. Rig: docker/recipes (sample RecipeValueName,RecipeValue files incl. an invalid one) bind-mounted read-only at /app/recipes on both site-a nodes with AllowedRoots [/app/recipes]. The TestMesMachine SimDelmiaRecipe simulator now reads + parses the downloaded file, converts each value to its recipe tag's type and loads it all-or-nothing (14 new TestDelmiaReceiver attributes); verify-mes-test-machine.sh group A covers accept / re-download / invalid lines / NotFound / OutsideAllowedRoots, VERIFY_GROUPS selects groups (rig: AD).
This commit is contained in:
@@ -231,7 +231,7 @@ spec for each is `docs/requirements/Component-<Name>.md`, and `README.md` carrie
|
||||
### Akka.NET Conventions
|
||||
- Tell for hot-path internal communication; Ask reserved for system boundaries.
|
||||
- Cross-cluster communication is gRPC (per-site PSK-authenticated): site→central `CentralControlService`, central→site `SiteCommandService`, plus the `SiteStreamService` data stream. ClusterClient/ClusterClientReceptionist were removed in the migration's Phase 4 — service discovery is by dialling configured endpoints, not the receptionist. (Akka.Cluster.Tools remains for ClusterSingleton.)
|
||||
- Script trust model: forbidden APIs (System.IO, Process, Threading, Reflection, raw network). The trust boundary is centralized in the Script Analysis component (#25) — `ScriptTrustPolicy` is the single source of truth; all four call sites (Template Engine, Site Runtime, Inbound API, Central UI) delegate to `ScriptTrustValidator`. The design-time deploy gate in Template Engine is authoritative (real semantic compile), not advisory. Every Roslyn script-compile surface must also attach the shared `CachingScriptMetadataResolver.Instance` (ScriptAnalysis) via `ScriptOptions.WithMetadataResolver` — the four today are Site Runtime `ScriptCompilationService`, Inbound API `InboundScriptExecutor`, Central UI `ScriptAnalysisService`, and ScriptAnalysis `RoslynScriptCompiler`; a new surface that omits it silently reintroduces a per-compile native metadata leak (see Component-ScriptAnalysis.md).
|
||||
- Script trust model: forbidden APIs (System.IO, Process, Threading, Reflection, raw network). **One host-mediated exception (2026-09-28):** site scripts get a read-only `Files` global (`ReadTextAsync`/`ReadLinesAsync`/`ExistsAsync`) that reads only beneath `ScadaBridge:SiteRuntime:ScriptFileAccess:AllowedRoots` — **off by default** (empty ⇒ every call throws `ScriptFileAccessException(Disabled)`), canonical-path directory-boundary match, no symlinks/junctions below a root, `MaxFileBytes` cap (1 MiB). The script still never names a `System.IO` type; errors are the Commons `ScriptFileAccessException`, and `Commons.Types.Scripts` is now a default script import on every surface. Not on inbound (central) scripts; the Test Run sandbox binds it but refuses. Design: `docs/plans/2026-09-28-script-file-access-design.md`. The trust boundary is centralized in the Script Analysis component (#25) — `ScriptTrustPolicy` is the single source of truth; all four call sites (Template Engine, Site Runtime, Inbound API, Central UI) delegate to `ScriptTrustValidator`. The design-time deploy gate in Template Engine is authoritative (real semantic compile), not advisory. Every Roslyn script-compile surface must also attach the shared `CachingScriptMetadataResolver.Instance` (ScriptAnalysis) via `ScriptOptions.WithMetadataResolver` — the four today are Site Runtime `ScriptCompilationService`, Inbound API `InboundScriptExecutor`, Central UI `ScriptAnalysisService`, and ScriptAnalysis `RoslynScriptCompiler`; a new surface that omits it silently reintroduces a per-compile native metadata leak (see Component-ScriptAnalysis.md).
|
||||
- Application-level correlation IDs on all request/response messages.
|
||||
|
||||
## Tool Usage
|
||||
|
||||
Reference in New Issue
Block a user