Skip to content

Add MXC preflight diagnostics#480

Merged
shanselman merged 1 commit into
masterfrom
mxc-preflight-diagnostics
May 21, 2026
Merged

Add MXC preflight diagnostics#480
shanselman merged 1 commit into
masterfrom
mxc-preflight-diagnostics

Conversation

@shanselman
Copy link
Copy Markdown
Contributor

Summary

  • log the sandbox settings snapshot alongside each system.run sandbox request
  • add JS bridge path accounting for C# policy, SDK-added tool/temp grants, scoped removals, denied-overlap removals, and scratch grants
  • write preflight policy/config/spawn artifacts while MXC execution is intentionally skipped for debugging

Validation

  • node --check tools\mxc\run-command.cjs
  • dotnet test .\tests\OpenClaw.Shared.Tests\OpenClaw.Shared.Tests.csproj --no-restore --filter FullyQualifiedName~MxcCommandRunnerTests
  • .\build.ps1
  • dotnet test .\tests\OpenClaw.Shared.Tests\OpenClaw.Shared.Tests.csproj --no-restore — 1804 passed / 28 skipped
  • dotnet test .\tests\OpenClaw.Tray.Tests\OpenClaw.Tray.Tests.csproj --no-restore — 1149 passed

Log sandbox settings snapshots, bridge request lifecycle, effective policy path accounting, and preflight artifacts so sandbox policy drops can be debugged before running MXC.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@shanselman shanselman merged commit 8717e82 into master May 21, 2026
23 checks passed
@shanselman shanselman deleted the mxc-preflight-diagnostics branch May 21, 2026 05:28
bkudiess added a commit to bkudiess/openclaw-windows-node that referenced this pull request May 21, 2026
Removes the Node.js + @microsoft/mxc-sdk + tools/mxc/run-command.cjs path for
MXC AppContainer sandboxing and replaces it with a pure-C# pipeline that calls
wxc-exec.exe directly. node.exe is no longer required at runtime.

Key changes:
- MxcConfigBuilder: pure function building wxc-exec ContainerConfig from
  SandboxExecutionRequest + scratch dir. Owns env allow-list + scrub, PATH
  tool resolution, shell command-line construction, cwd auto-grant.
- DirectAppContainerExecutor: ISandboxExecutor that creates per-invocation
  scratch dir, builds the config, logs a redacted summary (full JSON behind
  OPENCLAW_MXC_LOG_FULL_CONFIG=1), handles timeout/cancel, and falls back to
  --config <file> when the base64 config exceeds the cmdline limit.
- MxcExecutor (in OrcaCore.Models/Services for cross-project compat):
  additive caps + RunWithConfigFileAsync. Uses ProcessStartInfo.ArgumentList
  to avoid manual quoting hazards. WaitForExit() after kill so async stdout
  /stderr handlers drain before we read.
- MxcAvailability: no more RunCommandScriptPath; probes tools/mxc/<arch>/
  wxc-exec.exe first, legacy node_modules fallback.
- MxcCommandRunner: applies PR openclaw#480 diagnostic logging
  (LogSandboxRequest/LogSandboxResult) so sandbox settings round-tripping
  through wxc-exec is verifiable. CWD is logged as <set>/<null>, not the
  literal path.
- csproj: replaces 4 SDK/bridge copy targets with CopyWxcExecToOutput,
  CopyWxcExecToPublish, ValidateWxcExecShipped, ValidateWxcExecPublished,
  and a ValidateMxcArchMapping target that errors on unmapped RIDs.
- Tests: MxcConfigBuilderTests with 4 SDK-captured golden JSONs
  (LockedDown/Balanced/Permissive/Custom) for byte-equivalence vs the
  SDK output, plus env-scrub case-insensitivity, ResolveToolDirsFromPath,
  cwd auto-grant, timeout defaulting. DirectAppContainerExecutorTests
  cover the fail-fast paths. Symmetric golden compare with an explicit
  allow-list for the fields the SDK leaves empty.

Security hardening surfaced by adversarial review:
- IsDriveRoot guard in ResolveToolDirsFromPath prevents a misconfigured PATH
  entry from granting the whole system drive as readonly.
- CONNECTION_STRING and CONNSTR markers added to credential env-scrub.
- Env dict uses OrdinalIgnoreCase so an agent cannot inject a case-variant
  duplicate of a host-allowlisted var (APPDATA vs appdata).
- Reject embedded quotes in --config path; ArgumentList everywhere else.
- Host-side CancelAfter mirrors the builder's effective timeout (no
  unbounded wait when request.TimeoutMs is 0).
- ct.ThrowIfCancellationRequested() before the timeout branch so caller
  cancellation isn't mislabeled as TimedOut.
- UTF-8 byte count for the base64 cmdline-overflow threshold.

Removed:
- src/OpenClaw.Shared/Mxc/OneShotAppContainerExecutor.cs
- tools/mxc/run-command.cjs

Subsumes openclaw#480.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
bkudiess added a commit to bkudiess/openclaw-windows-node that referenced this pull request May 21, 2026
Removes the Node.js + @microsoft/mxc-sdk + tools/mxc/run-command.cjs path for
MXC AppContainer sandboxing and replaces it with a pure-C# pipeline that calls
wxc-exec.exe directly. node.exe is no longer required at runtime.

Key changes:
- MxcConfigBuilder: pure function building wxc-exec ContainerConfig from
  SandboxExecutionRequest + scratch dir. Owns env allow-list + scrub, PATH
  tool resolution, shell command-line construction, cwd auto-grant.
- DirectAppContainerExecutor: ISandboxExecutor that creates per-invocation
  scratch dir, builds the config, logs a redacted summary (full JSON behind
  OPENCLAW_MXC_LOG_FULL_CONFIG=1), handles timeout/cancel, and falls back to
  --config <file> when the base64 config exceeds the cmdline limit.
- MxcExecutor (in OrcaCore.Models/Services for cross-project compat):
  additive caps + RunWithConfigFileAsync. Uses ProcessStartInfo.ArgumentList
  to avoid manual quoting hazards. WaitForExit() after kill so async stdout
  /stderr handlers drain before we read.
- MxcAvailability: no more RunCommandScriptPath; probes tools/mxc/<arch>/
  wxc-exec.exe first, legacy node_modules fallback.
- MxcCommandRunner: applies PR openclaw#480 diagnostic logging
  (LogSandboxRequest/LogSandboxResult) so sandbox settings round-tripping
  through wxc-exec is verifiable. CWD is logged as <set>/<null>, not the
  literal path.
- csproj: replaces 4 SDK/bridge copy targets with CopyWxcExecToOutput,
  CopyWxcExecToPublish, ValidateWxcExecShipped, ValidateWxcExecPublished,
  and a ValidateMxcArchMapping target that errors on unmapped RIDs.
- Tests: MxcConfigBuilderTests with 4 SDK-captured golden JSONs
  (LockedDown/Balanced/Permissive/Custom) for byte-equivalence vs the
  SDK output, plus env-scrub case-insensitivity, ResolveToolDirsFromPath,
  cwd auto-grant, timeout defaulting. DirectAppContainerExecutorTests
  cover the fail-fast paths. Symmetric golden compare with an explicit
  allow-list for the fields the SDK leaves empty.

Security hardening surfaced by adversarial review:
- IsDriveRoot guard in ResolveToolDirsFromPath prevents a misconfigured PATH
  entry from granting the whole system drive as readonly.
- CONNECTION_STRING and CONNSTR markers added to credential env-scrub.
- Env dict uses OrdinalIgnoreCase so an agent cannot inject a case-variant
  duplicate of a host-allowlisted var (APPDATA vs appdata).
- Reject embedded quotes in --config path; ArgumentList everywhere else.
- Host-side CancelAfter mirrors the builder's effective timeout (no
  unbounded wait when request.TimeoutMs is 0).
- ct.ThrowIfCancellationRequested() before the timeout branch so caller
  cancellation isn't mislabeled as TimedOut.
- UTF-8 byte count for the base64 cmdline-overflow threshold.

Removed:
- src/OpenClaw.Shared/Mxc/OneShotAppContainerExecutor.cs
- tools/mxc/run-command.cjs

Subsumes openclaw#480.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
bkudiess added a commit to bkudiess/openclaw-windows-node that referenced this pull request May 21, 2026
Removes the Node.js + @microsoft/mxc-sdk + tools/mxc/run-command.cjs path for
MXC AppContainer sandboxing and replaces it with a pure-C# pipeline that calls
wxc-exec.exe directly. node.exe is no longer required at runtime.

Key changes:
- MxcConfigBuilder: pure function building wxc-exec ContainerConfig from
  SandboxExecutionRequest + scratch dir. Owns env allow-list + scrub, PATH
  tool resolution, shell command-line construction, cwd auto-grant.
- DirectAppContainerExecutor: ISandboxExecutor that creates per-invocation
  scratch dir, builds the config, logs a redacted summary (full JSON behind
  OPENCLAW_MXC_LOG_FULL_CONFIG=1), handles timeout/cancel, and falls back to
  --config <file> when the base64 config exceeds the cmdline limit.
- MxcExecutor (in OrcaCore.Models/Services for cross-project compat):
  additive caps + RunWithConfigFileAsync. Uses ProcessStartInfo.ArgumentList
  to avoid manual quoting hazards. WaitForExit() after kill so async stdout
  /stderr handlers drain before we read.
- MxcAvailability: no more RunCommandScriptPath; probes tools/mxc/<arch>/
  wxc-exec.exe first, legacy node_modules fallback.
- MxcCommandRunner: applies PR openclaw#480 diagnostic logging
  (LogSandboxRequest/LogSandboxResult) so sandbox settings round-tripping
  through wxc-exec is verifiable. CWD is logged as <set>/<null>, not the
  literal path.
- csproj: replaces 4 SDK/bridge copy targets with CopyWxcExecToOutput,
  CopyWxcExecToPublish, ValidateWxcExecShipped, ValidateWxcExecPublished,
  and a ValidateMxcArchMapping target that errors on unmapped RIDs.
- Tests: MxcConfigBuilderTests with 4 SDK-captured golden JSONs
  (LockedDown/Balanced/Permissive/Custom) for byte-equivalence vs the
  SDK output, plus env-scrub case-insensitivity, ResolveToolDirsFromPath,
  cwd auto-grant, timeout defaulting. DirectAppContainerExecutorTests
  cover the fail-fast paths. Symmetric golden compare with an explicit
  allow-list for the fields the SDK leaves empty.

Security hardening surfaced by adversarial review:
- IsDriveRoot guard in ResolveToolDirsFromPath prevents a misconfigured PATH
  entry from granting the whole system drive as readonly.
- CONNECTION_STRING and CONNSTR markers added to credential env-scrub.
- Env dict uses OrdinalIgnoreCase so an agent cannot inject a case-variant
  duplicate of a host-allowlisted var (APPDATA vs appdata).
- Reject embedded quotes in --config path; ArgumentList everywhere else.
- Host-side CancelAfter mirrors the builder's effective timeout (no
  unbounded wait when request.TimeoutMs is 0).
- ct.ThrowIfCancellationRequested() before the timeout branch so caller
  cancellation isn't mislabeled as TimedOut.
- UTF-8 byte count for the base64 cmdline-overflow threshold.

Removed:
- src/OpenClaw.Shared/Mxc/OneShotAppContainerExecutor.cs
- tools/mxc/run-command.cjs

Subsumes openclaw#480.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant