You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
widget-creator: run widgets on the stable MXC SDK 1.0.1 (supersedes #906) - #1469
Moves Widget Creator off the vendored prereleasewxc-exec binaries (MXC v0.7.0-rc1) onto the stable, publicMicrosoft.Mxc.Sdk 1.0.1 NuGet package and its in-process Microsoft.Mxc.Sdk.V1 API. MXC v1.0.1 is a non-prerelease GitHub release, and the package is author-signed by Microsoft and countersigned by nuget.org. Supersedes #906. From #906 this keeps only Widget Creator's run-time Copilot CLI fallback (CopilotSdkClient.ResolveCliPath). Its build-time CLI acquisition targets are not included: GitHub.Copilot.SDK 1.0.28 already downloads the CLI from github/copilot-cli releases, checks it against SHA256SUMS.txt, and supports mirrors.
Sandbox (MxcSandbox)
Widgets launch through MxcContainer.SpawnAsync on the Containment.ProcessContainer backend; wxc-exec is no longer run.
stdout/stderr stream into the log. MXC warnings are logged at spawn and again after the wait, because MXC can add more during finalization.
MXC timeouts and host cancellation are reported with the existing WIDGET_SANDBOX_TIMEOUT marker.
These are reported as sandbox errors, never as widget crashes, so they never trigger the AI repair loop:
MxcException and SDK argument errors at spawn;
an MxcException from the wait;
an unexpected output-reader failure;
a failed containment check, including one that races with cancellation.
If the sandbox can't run a widget's self-test, the widget is saved but not launched, and the reason is shown.
The stream closers used during the drain grace period are disposed after use; each closer access returns a new native handle.
Runtime integrity (C-3, MxcNativeRuntime)
Package signing only authenticates at restore time. The SDK's own native loader also honors MXC_FFI_DIR and developer build paths without verifying them.
So at startup, before any MXC call, the host:
claims the SDK assembly's DllImport resolver;
resolves mxc_ffi only from the app's packaged native assets;
requires mxc_ffi.dlland every companion native (plm.exe, wslcsdk.dll, wxc-wslc-daemon.exe) to be present as regular files at the expected path. The canonical path is taken from the open handle, so symbolic links, junctions and redirected paths are rejected;
holds them open read-share-only, so neither they nor their folders can be swapped, renamed or deleted;
requires a valid Authenticode signature (WinVerifyTrust) whose leaf is O=Microsoft Corporation, with a chain that ends in a genuine Microsoft root. The root is checked by public key using CERT_CHAIN_POLICY_MICROSOFT_ROOT, not by name;
loads exactly that file.
Any failure leaves the sandbox unavailable (fail closed). This replaces the removed hash pins without pinning anything.
Trust boundary (documented): the app's own folder must not be writable by untrusted users. The .NET runtime itself probes it for bare-named native libraries before any app code runs, and anyone who can write there could replace WidgetCreator.dll anyway.
Policy (MxcPolicy)
The per-widget policy JSON uses MXC 1.0 field names: filesystem.*, network.egress{default,allow,deny}, network.ingress{default,hostLoopback}, ui.*, and processContainer.capabilities.
It is validated as a closed document, like the MXC contract, and mapped to the typed ContainerRequest. Validation rejects:
unknown fields, explicit null values, and duplicate keys;
CIDRs MXC wouldn't parse. This mirrors Rust cidr::IpCidr: strict IPv4 and IPv6 text, host bits zero, each except inside its cidr;
empty to / ports lists;
invalid port selectors (endPort needs port and must be ≥ it; ICMP takes no ports).
Policies saved in the old 0.6.0-alpha format are migrated when read. The old default policy migrates exactly to the new default.
Migration fails closed: a legacy policy is reported as invalid when it uses settings MXC 1.0 can't express (for example network.blockedHosts or leastPrivilege: true), or when its known fields are malformed. The widget then runs with the default policy, and the run log shows a visible warning naming the settings that were not applied.
dotnet test tests/Reactor.Tests -p:Platform=x64 -p:SkipSignaturesGen=true --filter "FullyQualifiedName~WinAppSDKReferenceGuardTests": passed (86/86)
Real app startup: WidgetCreator.exe --check-runtime (RID-less runtimes\win-x64\native layout) logs "MXC native runtime verified (Microsoft-signed) and bound".
NativeAOT: an earlier full WidgetCreator publish opened its window and loaded MXC native 1.0.1. That publish needed -p:WarningsNotAsErrors=CA1416 for a pre-existing error in WindowsAppRuntimeCheck.cs, unchanged from main. The native gate (resolver claim, Authenticode, Microsoft-root policy, final-path check) was also re-run in a NativeAOT build of the harness below.
Local scratch harness (not committed). It compiles the real MxcPolicy / MxcSandbox / MxcContainmentVerifier / MxcNativeRuntime sources and runs real sandboxed processes. All checks passed:
Policy:
mapping of default, mutated and legacy policies;
rejection of unknown fields, nulls, duplicate keys, bad clipboard values, ports, CIDRs, except entries and empty selectors;
fail-closed legacy migration, including malformed fields;
a visible warning when a stored policy is replaced.
CIDR parity with real MXC: a set of tricky IPv4/IPv6 peers (mapped, cross-family except, bracketed or short forms) was checked with both our validator and a real MXC 1.0.1 spawn, and every case agreed.
Run behavior:
stdout streaming and exit codes;
MXC timeout (about 2s);
host cancellation (kill, 0xC000013A).
Filesystem and network:
a file under the user profile can't be read by default, and becomes readable when granted;
curl to nuget.org fails by default and returns HTTP 200 with Internet access.
Native gate (C-3):
with a decoy signed mxc_ffi.dll in MXC_FFI_DIR, only the verified app-local DLL loads;
a tampered mxc_ffi.dll or plm.exe fails (0x80096010);
a validly signed non-Microsoft binary fails the Microsoft-root policy (0x800B0109);
launching through a junction, a symlinked mxc_ffi.dll, and a missing wslcsdk.dll are all rejected;
Windows refuses to rename a parent folder while the files are pinned.
Token check: every run was verified as AppContainer at low integrity.
Real window: a framework-dependent Reactor/WinUI app (the shape of generated widgets) launched under the default policy and created its top-level window.
Not run: the full generate → build → run flow with Copilot.
Needs human validation: running on arm64 hardware, and a specialist review of the Windows security mechanisms (Authenticode, native loading, file pinning). Copilot's latest review flags these as needing a closer look; it has no open issues.
Note: a self-contained WinUI app fails at Application.Start (CLASS_E_CLASSNOTAVAILABLE) under ProcessContainer. The old vendored wxc-exec 0.7.0-rc1 fails the same way, so this is not a regression. Generated widgets are framework-dependent and are not affected.
Risk / breaking changes
Sample only. No public Reactor API changes. Adds one central PackageVersion (Microsoft.Mxc.Sdk 1.0.1). No build-wide changes: Directory.Build.targets and the pipeline templates are unchanged from main.
Stored policies: existing per-widget policies are migrated in memory when read. A legacy policy with unsupported or malformed settings runs with the default policy, with a visible warning, until the user reviews and saves it. Hand-edited policies with nulls, duplicate keys or lax CIDR syntax are now reported as invalid.
Fail-closed sandbox availability: if the MXC natives are missing, modified, linked, or not Microsoft-signed, the sandbox reports itself as unavailable instead of running widgets. Launching the app through a junction or symbolic link to its folder also makes the sandbox unavailable.
Removed overrides: the WIDGET_CREATOR_*MXC* / WXC_EXEC environment overrides and the least-privilege toggle are gone. MXC 1.0 always runs with least privilege off.
Make the GitHub.Copilot.SDK build-time CLI acquisition resilient and
internal/external-aware.
Copilot CLI acquisition (build/Reactor.CopilotCli.targets, imported from
Directory.Build.targets):
- The SDK's targets download copilot.exe with an unauthenticated MSBuild
DownloadFile hardcoded to registry.npmjs.org and <Error> on failure
(MSB3923), breaking `dotnet build`/`run` on offline/proxied/TLS-intercepted
networks. The CLI is a runtime-only artifact. CI skips it; local dev did not.
- New shared target takes over acquisition (evaluation-time, so it gates the
SDK's own targets) and obtains the CLI best-effort: cached -> COPILOT_CLI_PATH
-> public DownloadFile (external/OSS) -> `npm pack` honoring an authenticated
.npmrc (internal Azure Artifacts feed) -> else build succeeds WITHOUT a bundled
CLI plus a REACTORCLI001 warning. Inert when CopilotSkipCliDownload=true.
- CopilotSdkClient resolves a CLI at run time (bundled -> COPILOT_CLI_PATH ->
installed) and passes RuntimeConnection.ForStdio(path:), since the SDK default
only looks for a bundled binary and ignores COPILOT_CLI_PATH.
- Internal npm feed modernized to the pkgs.dev.azure.com domain (matching the
NuGet feed's org/project); README documents the internal/external behavior.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 37ad0486-7427-4b45-8216-b11a2d06d00a
- CopilotSdkClient.ResolveCliPath no longer scans PATH for copilot.exe (a
malicious/unrelated copilot.exe earlier on PATH could otherwise be launched).
It now resolves only the bundled CLI, COPILOT_CLI_PATH, and the well-known
per-user GitHub CLI install location; updated the doc comment to match.
- README: reword the offline bullet so it no longer reads as if `gh auth`
itself provides a runnable copilot.exe (it only supplies credentials).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 37ad0486-7427-4b45-8216-b11a2d06d00a
Replace the vendored prerelease wxc-exec binaries (MXC v0.7.0-rc1) with the
stable, Microsoft-signed Microsoft.Mxc.Sdk 1.0.1 NuGet package and its
in-process Microsoft.Mxc.Sdk.V1 API.
- MxcSandbox launches widgets with MxcContainer.SpawnAsync on the
ProcessContainer backend, streams stdout/stderr, maps MXC timeouts and
cancellation to WIDGET_SANDBOX_TIMEOUT, and reports MxcException as an
explicit launch error (never a widget crash).
- MxcPolicy: per-widget policy JSON now mirrors MXC 1.0 field names
(filesystem / network.egress+ingress / ui / processContainer.capabilities),
is validated as a closed document, migrates legacy 0.6.0-alpha policies on
read, and maps to the typed ContainerRequest.
- MxcContainmentVerifier: strict BaseContainer mode uses MxcContainer.Probe;
the out-of-band token check inspects the SDK-reported contained PID.
- Permissions dialog: drop the least-privilege toggle (not exposed by MXC
1.0), map "Allow local network" to ingress allow, add write/all clipboard
levels, surface advanced egress rules as "Custom".
- Self-test runs that fail to launch in the sandbox are no longer sent to
Copilot for repair.
- Delete tools/mxc/** (x64 + arm64 binaries), MxcBinaryManifest hash pins,
the csproj copy item, and the WIDGET_CREATOR_WXC_EXEC / _MXC_BIN /
_USE_LOCAL_MXC / _MXC_ROOT overrides; update the README.
Supersedes #906 (its Copilot CLI build-resilience commits are kept).
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Artifact sizes for ea7a596 vs the base branch (57a5106).
Packages (compressed .nupkg)
Artifact
base
PR
Δ
Microsoft.UI.Reactor.nupkg
2.00 MB
2.00 MB
-6 B (0.00%)
≈
Microsoft.UI.Reactor.Advanced.nupkg
495.8 KB
495.8 KB
-3 B (0.00%)
≈
Microsoft.UI.Reactor.Devtools.nupkg
287.8 KB
287.8 KB
-4 B (0.00%)
≈
Assemblies in Microsoft.UI.Reactor
Artifact
base
PR
Δ
Reactor.Analyzers.dll
411.5 KB
411.5 KB
+0 B (0.00%)
≈
Reactor.dll
2.75 MB
2.75 MB
+0 B (0.00%)
≈
Reactor.Localization.Generator.dll
16.0 KB
16.0 KB
+0 B (0.00%)
≈
Reactor.Wrappers.Abstractions.dll
10.5 KB
10.5 KB
+0 B (0.00%)
≈
Reactor.Wrappers.Generator.dll
145.5 KB
145.5 KB
+0 B (0.00%)
≈
Assemblies in Microsoft.UI.Reactor.Advanced
Artifact
base
PR
Δ
Reactor.Advanced.dll
1.00 MB
1.00 MB
+0 B (0.00%)
≈
Assemblies in Microsoft.UI.Reactor.Devtools
Artifact
base
PR
Δ
Microsoft.UI.Reactor.Devtools.dll
787.5 KB
787.5 KB
+0 B (0.00%)
≈
No size change beyond the noise floor. ✅
✅ smaller / ⚠️ larger / ≈ within noise. Sizes come from a Release dotnet pack on the CI runner: packages are the compressed .nupkg download size, assemblies the uncompressed DLL inside it. workflow run.
Coverage for ea7a596 vs the base branch (8ef5f38) — unit + selftest merged.
Metric
base
PR
Δ
Line
88.37%
88.38%
+0.01 pp
≈
Branch
47.01% (17571/37374)
47.02% (17572/37374)
+0.01 pp
≈
No coverage change beyond the noise floor. ✅
✅ higher / ⚠️ lower / ≈ within noise. Δ is in percentage points; coverage is unit + selftest merged (Debug x64) on the CI runner. Cobertura reports attached to the workflow run as artifacts.
- Narrow generic catch clauses in MxcSandbox: native-runtime probes catch
only native load/MXC failures, verifier awaits catch only
OperationCanceledException, and stream-closer cleanup catches only
MxcException/IOException/ObjectDisposedException.
- Use Path.Join (never drops earlier segments) and FirstOrDefault in
CopilotSdkClient.ResolveCliPath; use Where in MxcPolicy legacy migration.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- Drop build/Reactor.CopilotCli.targets (+ its Directory.Build.targets import
and the npm-feed pipeline tweak) carried over from #906. It forced
CopilotSkipCliDownload=true and replaced GitHub.Copilot.SDK 1.0.28's
SHA256SUMS-verified download from github/copilot-cli releases with an
unverified npm tarball, and ignored the SDK's CopilotCliReleaseBaseUrl /
COPILOT_CLI_DOWNLOAD_BASE_URL / CopilotCliBinaryPath hooks. Keep
CopilotSdkClient.ResolveCliPath as the sample's run-time fallback and
document the SDK hooks in the README instead.
- Legacy policy migration fails closed: policies with settings MXC 1.0 can't
express (e.g. network.blockedHosts, leastPrivilege: true) are reported as
invalid and the widget falls back to the default policy instead of having
those restrictions silently dropped.
- Do not relaunch a build whose self-test the sandbox could not run (incl. a
failed containment check); save it and explain instead.
- Treat self-test output in the repair prompt as untrusted data
(SanitizeUntrusted + WIDGET_OUTPUT markers), like crash output.
- Reject blank CIDRs and route SDK argument validation errors to the
launch-failure path.
- Only offer "local network" together with internet access (MXC's
AppContainer fallback rejects inbound-only private network access);
"No network access" now also closes ingress.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
The first SDK call can load a substituted native DLL into the unsandboxed host before later checks, leaving a critical runtime-substitution vulnerability.
Migrates Widget Creator from vendored prerelease MXC executables to the stable Microsoft.Mxc.Sdk 1.0.1 in-process sandbox API, superseding #906 without its build-time CLI acquisition changes.
Changes:
Replaces executable-based sandboxing with SDK requests, streamed output, and updated containment checks.
Adds policy migration and validation, updates permissions controls, and prevents sandbox launch failures from triggering repair or automatic relaunch.
Retains runtime Copilot CLI fallback and removes obsolete MXC binaries, integrity pins, and deployment instructions.
- Verify and bind the MXC native runtime before the first SDK call (C-3): claim the SDK's DllImport resolver, load only the app's packaged mxc_ffi.dll after pinning it and its companion natives and requiring a Microsoft Authenticode signature; fail closed otherwise.
- Report unexpected MXC output-stream failures as sandbox errors instead of silently truncating the log.
- Validate egress CIDRs (MXC 1.0 syntax, host bits, except containment) and port selectors (endPort needs port, ascending, no ports for ICMP).
- 'No network access' also clears egress.deny rules.
- Surface a visible run-log warning when a stored policy can't be applied and the default replaces it.
- Use Where in UnsupportedLegacyFields.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
Process completion and cleanup warnings are silently dropped, and the CLI fallback misses the standard user-scoped WinGet location, causing generation to fail despite an installed CLI.
A standard user-scoped winget install GitHub.Copilot exposes the executable at %LOCALAPPDATA%\Microsoft\WinGet\Links\copilot.exe, not this location. With CopilotSkipCliDownload=true and no COPILOT_CLI_PATH, this fallback therefore returns null despite an installed CLI, and generation still fails looking for the missing bundled binary. Include the fixed WinGet location without scanning PATH.
MXC's MxcProcess.Warnings includes diagnostics added during terminal wait/finalization, not just spawn warnings. Reading it only here silently drops completion and cleanup warnings when the process is later disposed, so the shell can report a clean exit without showing that cleanup failed. Re-read and log newly added warnings after WaitAsync completes, before disposal, while retaining the early warnings for long-running widgets.
- Log MXC warnings appended during wait/finalization, not only spawn warnings.
- Resolve the Copilot CLI from the WinGet GitHub.Copilot command links (user and machine scope) as fixed install locations; still no PATH scan.
- LINQ nits in MxcPolicy.IsValidPort and MxcNativeRuntime; ExactSpelling on the WinTrust imports.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
The DLL trust gate matches certificate names rather than cryptographic identity, allowing an attacker-controlled CA installed in CurrentUser\Root to authorize a non-Microsoft DLL for loading into the unsandboxed host.
No open issues 🎉
3 previously missed issues
In code that hasn't changed since last review
Validate signer against trusted Microsoft root identities
The Microsoft-root check uses a certificate display name, not a cryptographic identity. A replacement DLL signed by an attacker-controlled CA installed in CurrentUser\Root can pass WinVerifyTrust while using a root named “Microsoft Root Certificate Authority …” and a leaf with O=Microsoft Corporation. This would let a non-Microsoft DLL pass the C-3 gate and load into the unsandboxed host. Validate the chain with the Windows Microsoft-root chain policy (without test-root allowances), or verify approved Microsoft root public keys, rather than matching subject names.
Explicit empty selectors such as {"to":[]} or {"ports":[]} pass validation, but MXC 1.0.1 rejects them before launch. Users can therefore save a policy that prevents the widget from running. Reject empty selector arrays; users can omit the field to match all destinations or ports.
Handle MXC wait failures without aborting widget saves
MxcProcess.WaitAsync can throw MxcException from its status poll or native wait/finalization, but this block handles only cancellation. That host-side failure escapes RunAsync; during generation or refinement it aborts the pipeline before _library.SaveAsync, rather than saving the built widget without launching it. Handle MXC wait failures as sandbox results too, cleaning up the verifier and output pumps before returning a result with LaunchError set.
- Verify the MXC native runtime's signer chain with CERT_CHAIN_POLICY_MICROSOFT_ROOT (public-key check, 2011 application root, no test roots) on the chain WinVerifyTrust validated, instead of matching the root's display name.
- Reject explicit empty 'to' / 'ports' selector arrays, which MXC 1.0 refuses.
- Treat an MxcException from WaitAsync as a sandbox failure: kill, clean up the verifier and pumps, and return LaunchError so the widget is still saved.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
Human assessment is needed because legacy-policy migration can silently discard access denials while retaining broad grants, expanding access without triggering the intended default-policy fallback.
- Legacy policy migration fails closed on malformed known fields and non-object sections, so a denial (e.g. deniedPaths, ui.disable) can't be dropped while grants carry over.
- Filter the containment-verifier catch explicitly (best effort; cancellation propagates).
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- Reject explicit JSON nulls anywhere in a widget policy: an unset value maps to its default, so e.g. an allow rule's "to": null would match every destination and a null except/deniedPaths would drop a restriction.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
Human assessment is needed because a cancellation race can discard a confirmed sandbox containment failure and misclassify it as a repairable widget error.
- On cancellation/timeout, await the containment verifier before classifying: a containment failure it confirmed is reported as a sandbox failure, never as a repairable timeout.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
Human assessment is needed because a critical native-library substitution risk could allow attacker-controlled code to execute in the unsandboxed host before runtime verification.
- Document the C-3 trust boundary: the app's own folder must not be writable by untrusted users. The .NET runtime probes it for bare-named native libraries (verified: a planted crypt32/advapi32/kernel32 is loaded by the runtime itself) and such a writer could replace WidgetCreator.dll anyway, so the gate covers substitution from outside that folder and tampering/linking/removal of the shipped MXC files.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
Human assessment is needed because duplicate policy keys can trigger an uncaught validation exception that faults rendering instead of displaying an invalid-policy message.
- Reject duplicate keys when parsing a widget policy (AllowDuplicateProperties = false) and treat ArgumentException from the JSON DOM as an invalid policy, so a duplicate key shows the invalid-policy message instead of faulting rendering.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
Human assessment is needed because the grace-period cleanup has subtle native-handle disposal behavior that can retain resources across repeated slow-drain runs.
- Dispose the MXC stream closers used during the drain grace period: each StandardOutputCloser/StandardErrorCloser access returns an independent native handle (per the SDK docs), so they were previously left for the finalizer.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
Human assessment is needed because an unpublished validation finding indicates that accepted IPv6 input can produce a saved policy that fails at launch.
- Parse IPv6 CIDRs as strictly as MXC's Rust parser: hex groups and ':' only, with an optional strict trailing dotted-quad. IPAddress.TryParse alone tolerated brackets, ports, zone IDs and short embedded IPv4, which MXC then rejected at launch. Cross-checked against real MXC 1.0.1 spawns.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
The security-boundary changes rely on Windows-specific Authenticode, native-loader, and file-pinning guarantees that could not be independently exercised and require specialist validation, particularly on ARM64.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ready-for-reviewAgent work and technical checks complete; awaiting review, not approval or merge
3 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Moves Widget Creator off the vendored prerelease
wxc-execbinaries (MXCv0.7.0-rc1) onto the stable, publicMicrosoft.Mxc.Sdk1.0.1 NuGet package and its in-processMicrosoft.Mxc.Sdk.V1API. MXC v1.0.1 is a non-prerelease GitHub release, and the package is author-signed by Microsoft and countersigned by nuget.org. Supersedes #906. From #906 this keeps only Widget Creator's run-time Copilot CLI fallback (CopilotSdkClient.ResolveCliPath). Its build-time CLI acquisition targets are not included:GitHub.Copilot.SDK1.0.28 already downloads the CLI fromgithub/copilot-clireleases, checks it againstSHA256SUMS.txt, and supports mirrors.Sandbox (
MxcSandbox)MxcContainer.SpawnAsyncon theContainment.ProcessContainerbackend;wxc-execis no longer run.WIDGET_SANDBOX_TIMEOUTmarker.MxcExceptionand SDK argument errors at spawn;MxcExceptionfrom the wait;Runtime integrity (C-3,
MxcNativeRuntime)MXC_FFI_DIRand developer build paths without verifying them.DllImportresolver;mxc_ffionly from the app's packaged native assets;mxc_ffi.dlland every companion native (plm.exe,wslcsdk.dll,wxc-wslc-daemon.exe) to be present as regular files at the expected path. The canonical path is taken from the open handle, so symbolic links, junctions and redirected paths are rejected;WinVerifyTrust) whose leaf isO=Microsoft Corporation, with a chain that ends in a genuine Microsoft root. The root is checked by public key usingCERT_CHAIN_POLICY_MICROSOFT_ROOT, not by name;WidgetCreator.dllanyway.Policy (
MxcPolicy)filesystem.*,network.egress{default,allow,deny},network.ingress{default,hostLoopback},ui.*, andprocessContainer.capabilities.ContainerRequest. Validation rejects:nullvalues, and duplicate keys;cidr::IpCidr: strict IPv4 and IPv6 text, host bits zero, eachexceptinside itscidr;to/portslists;endPortneedsportand must be ≥ it; ICMP takes no ports).network.blockedHostsorleastPrivilege: true), or when its known fields are malformed. The widget then runs with the default policy, and the run log shows a visible warning naming the settings that were not applied.Containment checks (C-2,
MxcContainmentVerifier)WIDGET_CREATOR_REQUIRE_BASE_CONTAINER) usesMxcContainer.Probe(request).Tier == BaseContainer.Permissions dialog
egress.allow/egress.denyand closes ingress.Other
ResolveCliPathalso checks the WinGetGitHub.Copilotcommand links (user and machine scope). It still never scansPATH.Removed
tools/mxc/**(x64 and arm64 executables plus README).MxcBinaryManifest.csSHA-256 pins and the csproj copy item.WIDGET_CREATOR_WXC_EXEC,WIDGET_CREATOR_MXC_BIN,WIDGET_CREATOR_USE_LOCAL_MXC, andWIDGET_CREATOR_MXC_ROOToverrides.Linked issue / spec
Supersedes #906.
Test plan
Validated on Windows 11 26100.9711 x64. MXC's tier probe reports BaseContainer on this host.
dotnet build samples/apps/widget-creator/widget-creator.csproj -c Release -p:Platform=x64: passed, 0 warnings, 0 errorsdotnet build samples/apps/widget-creator/widget-creator.csproj -c Release -p:Platform=ARM64: passed. Only built; not run on arm64 hardware.pwsh tests/build_props/ci/CopilotSdkContract.Tests.ps1: passed (6/6)dotnet test tests/Reactor.Tests -p:Platform=x64 -p:SkipSignaturesGen=true --filter "FullyQualifiedName~WinAppSDKReferenceGuardTests": passed (86/86)WidgetCreator.exe --check-runtime(RID-lessruntimes\win-x64\nativelayout) logs "MXC native runtime verified (Microsoft-signed) and bound".WidgetCreatorpublish opened its window and loaded MXC native 1.0.1. That publish needed-p:WarningsNotAsErrors=CA1416for a pre-existing error inWindowsAppRuntimeCheck.cs, unchanged frommain. The native gate (resolver claim, Authenticode, Microsoft-root policy, final-path check) was also re-run in a NativeAOT build of the harness below.MxcPolicy/MxcSandbox/MxcContainmentVerifier/MxcNativeRuntimesources and runs real sandboxed processes. All checks passed:exceptentries and empty selectors;except, bracketed or short forms) was checked with both our validator and a real MXC 1.0.1 spawn, and every case agreed.0xC000013A).mxc_ffi.dllinMXC_FFI_DIR, only the verified app-local DLL loads;mxc_ffi.dllorplm.exefails (0x80096010);0x800B0109);mxc_ffi.dll, and a missingwslcsdk.dllare all rejected;Application.Start(CLASS_E_CLASSNOTAVAILABLE) under ProcessContainer. The old vendoredwxc-exec0.7.0-rc1 fails the same way, so this is not a regression. Generated widgets are framework-dependent and are not affected.Risk / breaking changes
PackageVersion(Microsoft.Mxc.Sdk1.0.1). No build-wide changes:Directory.Build.targetsand the pipeline templates are unchanged frommain.nulls, duplicate keys or lax CIDR syntax are now reported as invalid.WIDGET_CREATOR_*MXC*/WXC_EXECenvironment overrides and the least-privilege toggle are gone. MXC 1.0 always runs with least privilege off.