BaseContainer: Ephemeral sandbox lifecycle cleanup (Part 1)#321
Conversation
Implements proper AppContainer profile cleanup for the BaseContainer runner when `destroy_on_exit: true` is configured.
### What it does
- **Ephemeral identities**: Every BaseContainer launch gets a unique `sandbox-{random hex}` identity, ensuring no profile collisions between concurrent sandboxes.
- **Registry tracking**: Before launch, writes a tracking entry under `HKLM\SOFTWARE\Microsoft\MxcSandbox\Tracking\{SID}` with metadata (identity, SID, origin, requested identity, timestamps). A volatile `Active` subkey marks in-flight sandboxes for crash detection.
- **Cleanup on exit**: After the sandboxed process exits, cleans up BFS filesystem policies (`bfscfg --removepolicy`) then deletes the AppContainer profile. Removes the tracking entry on success.
- **Deferred cleanup**: If a network proxy is configured, cleanup is skipped (proxy state can't be torn down yet). A `CleanupDeferred` marker is written to the tracking entry for future tooling.
- **Ctrl+C handling**: Registers a console control handler so cleanup still runs on interrupt.
- **No-op when `destroy_on_exit: false`**: No tracking, no cleanup -- the profile persists across runs.
### Why
Previously, BaseContainer never cleaned up AppContainer profiles. Over time this leaks registry state and BFS policies. This brings BaseContainer in line with LXC's existing cleanup behavior and follows the Tessera sandbox lifecycle spec.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
| // Only runs when tracking was written (i.e., destroy_on_exit was true). | ||
| // Deferred if a network proxy is configured (proxy state can't be cleaned up yet). | ||
| if tracking_written { | ||
| run_sandbox_cleanup( |
There was a problem hiding this comment.
@bbonaby - do I need an RAII-like container for this cleanup in case someone early returns or an exception happens?
(early return on line 617, for example)
There was a problem hiding this comment.
@copilot do i need to wrap run_sandbox_cleanup in an RAII-like type?
There was a problem hiding this comment.
Just seeing this but I believe so, for what it's worth you might be able to use the scopeguard crate: https://crates.io/crates/scopeguard like you would with wil::scope_exit
There was a problem hiding this comment.
Pull request overview
This PR adds a Windows-only lifecycle tracking + cleanup mechanism for the BaseContainer backend to support lifecycle.destroy_on_exit: true, aiming to prevent long-term leaks of AppContainer profiles and BFS filesystem policy state.
Changes:
- Added a new
sandbox_trackingmodule that records per-sandbox tracking info in the registry, supports best-effort cleanup (BFS policy removal + AppContainer profile deletion), and installs a console control handler for interrupt cleanup. - Updated
BaseContainerRunnerto mint ephemeralsandbox-{hex}identities whendestroy_on_exitis enabled, write a pre-launch tracking entry, and perform best-effort cleanup on exit/failure/interrupt. - Added
FileSystemBfsManager::clear_policyto allow cleanup even when the BFS manager wasn’t previously “configured” within the current process.
Show a summary per file
| File | Description |
|---|---|
| src/wxc_common/src/sandbox_tracking.rs | New registry-based tracking + cleanup helpers, plus Ctrl+C/console-close cleanup hook and unit tests. |
| src/wxc_common/src/lib.rs | Exposes the new sandbox_tracking module on Windows builds. |
| src/wxc_common/src/filesystem_bfs.rs | Adds clear_policy() helper to unconditionally clear BFS policy for an identity. |
| src/wxc_common/src/base_container_runner.rs | Integrates ephemeral identity + tracking + cleanup into BaseContainer process launch and exit flow. |
Copilot's findings
- Files reviewed: 4/4 changed files
- Comments generated: 7
….com/microsoft/mxc into jsidewhite/mxc_lifecycle_cleanup_pr2
BaseContainer: Ephemeral sandbox lifecycle tracking
Implements proper AppContainer profile cleanup for the BaseContainer runner when
destroy_on_exit: trueis configured.What it does
sandbox-{random hex}identity, ensuring no profile collisions between concurrent sandboxes.HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\ProcessSandboxes\Mappings\{SID}with metadata (identity, SID, origin, requested identity, timestamps). A volatileActivesubkey marks in-flight sandboxes for crash detection.CleanupDeferredmarker is written to the tracking entry for future tooling.destroy_on_exit: false: No tracking, no cleanup -- the profile persists across runs.Why
Previously, BaseContainer never cleaned up AppContainer profiles. Over time this leaks registry state and BFS policies. This in the ==FUTURE== brings BaseContainer in line with LXC's existing cleanup behavior and follows the Tessera sandbox lifecycle spec.
This PR adds ephemeral sandbox lifecycle cleanup to the BaseContainer runner. When destroy_on_exit: true, each sandbox gets a unique random identity (sandbox-{hex}), a registry tracking entry under HKCU...\ProcessSandboxes\Mappings{SID} for crash recoverability. It also installs a Ctrl+C handler so cleanup runs on interrupt, and defers cleanup when a network proxy is active since proxy state can't yet be torn down.
Architecture