Skip to content

feat(mxc): add UI policy controls and provider credential management - #3296

Open
araza008 wants to merge 39 commits into
NVIDIA:mainfrom
araza008:akberr/credential-manager
Open

feat(mxc): add UI policy controls and provider credential management#3296
araza008 wants to merge 39 commits into
NVIDIA:mainfrom
araza008:akberr/credential-manager

Conversation

@araza008

Copy link
Copy Markdown
Contributor

Summary

Adds portable UI policy controls and end-to-end provider credential management for MXC, validating and substituting scoped credentials through the host proxy. It ensures Windows sandboxes can use credentials without receiving raw secrets, with fail-closed validation, trust-boundary documentation, and a hardened credential test runner.

Changes

  • Added portable sandbox UI policy controls.
  • Added MXC provider credential management.
  • Routed credential validation and substitution through the host proxy.
  • Authorized only provider-scoped environment access.
  • Reused credential snapshots during policy merge validation.
  • Rejected expired or near-expiry credential snapshots.
  • Added fail-closed, secret-redacting MXC credential tests.
  • Hardened the PowerShell test runner and improved diagnostics.
  • Documented MXC prerequisites, defaults, and host-proxy trust boundaries.

Testing

  • Ran mise run --skip-tools windows:ci successfully on an x64 Windows host.
  • Passed x64 and ARM64 workspace checks.
  • Passed x64 and ARM64 release builds for openshell-gateway.exe and openshell.exe.

Checklist

  • Follows Conventional Commits
  • Commits are signed off (DCO)
  • Architecture docs updated (if applicable)

araza008 and others added 30 commits September 10, 2026 23:22
Generate per-sandbox TLS state for the MXC host proxy so HTTPS L7 enforcement can use the same MITM path as Linux. Grant generated CA material to the MXC process and inject standard trust env vars, while matching Linux behavior by disabling TLS termination on CA setup failure and relying on proxy fail-closed handling.
The MXC e2e harness never actually exercised the fs scenarios: it started
the gateway once and patched agent_command per scenario AFTERWARDS, so the
running gateway kept launching the default demo agent (not shipped in the
kit) and every fs scenario failed with CreateProcessW error:2. It also
scored on the `sandbox create` exit code (non-zero due to the harmless
interactive attach), wrote sandbox records to the persistent gateway DB
(leaving orphans that collided on later runs), and its deny scenarios never
proved denial.

Changes:
- Start a FRESH gateway per scenario so each scenario's agent_command is
  actually loaded (root cause of CreateProcessW error:2).
- Score by on-disk artifact / expected outcome, not `sandbox create` exit.
- Real deny assertions: a control write to a granted path must succeed
  (proves the agent ran) while the denied write must be absent. fs-empty
  probes an ungranted out-of-share path (share_dir is mapped rw by design).
- Run the gateway on an ephemeral in-memory DB (sqlite::memory:) so the
  harness never writes to the persistent store and cannot leave orphan
  sandbox records; also use unique per-run sandbox names + pre-delete.
- Fix the process_container probe: use a real cwd + absolute cmd.exe
  (canonical wxc-exec does not expand %TEMP% -> 0x8007010B).
- Fix summary counts (@() so a single FAIL is counted and exit is non-zero).

Verified PASS=4 FAIL=0 on 7F203-MXC-003 (no BaseContainer velocity keys)
using a canonical wxc-exec build (AppContainer fallback).

Signed-off-by: Akber Raza <akberr@nvidia.com>
MXC process.timeout is wall-clock ms (wire.rs). The 10 value meant 10ms,
which the base-container tier (7F203-MXC-001/.181) enforced strictly and
timed the probe out. AppContainer path (.18/-003) happened to slip under
it. Bump to 30000ms so the process_container preflight probe is reliable
across both tiers.

Signed-off-by: Akber Raza <akberr@nvidia.com>
Signed-off-by: Shailendra Singh <shailendras@nvidia.com>
Signed-off-by: Akber Raza <akberr@nvidia.com>
Three fixes to support the release wxc-exec binary (BaseContainer dispatcher)
in addition to mxc-fixes-env-vars:

1. Seed process env from host (driver.rs)
   ProcessContainer starts with a completely blank environment -- no PATH,
   SystemRoot, or anything.  Seed the process env from the gateway host
   environment so the agent binary can locate DLLs and run.  Skip internal
   Windows drive-letter variables (keys starting with '=') which cause
   CreateProcessW to return ERROR_ENVVAR_NOT_FOUND.  User agent_env entries
   and TLS CA vars are applied as overrides on top of the host env.

2. Remove TLS readonly_paths grant (driver.rs)
   The release wxc-exec (BaseContainer dispatcher) requires write-DAC
   permission on every path in readonly_paths to set up AppContainer ACLs.
   Adding the proxy's temp TLS directory caused a DACL error and exit -1.
   The CA cert paths remain available to the agent via TLS env vars.

3. Remove allowedHosts from network JSON (mxc.rs)
   The release wxc-exec rejects network.allowedHosts / network.blockedHosts
   on Windows with "not yet supported".  Removed the loopback exemption
   attempt (127.0.0.1, ::1, localhost) from the network section.
   Intra-container loopback works natively in the release binary without
   it -- the spawner can connect to the server at 127.0.0.1:22000 directly.

Additional changes:
- mxc-ws-agent.rs: add relay-debug.txt error capture and relay-ready.txt
  marker for reliable timing of host client connections.
- mxc-ws-gateway.toml: debug = true for JSON config dump during diagnosis.
- run-ws-agent-test.ps1: default port changed to 17670 (gateway default);
  relay-ready.txt polling before ws-echo to avoid connecting before the
  spawner has established the proxy bridge.

Signed-off-by: Prashant Khodade <pkhodade@nvidia.com>
Signed-off-by: Akber Raza <akberr@nvidia.com>
Four robustness/correctness fixes from CodeRabbit:

1. Start-Gw: kill the spawned gateway before the "did not start within 30s"
   throw. If the process is alive but never binds the port, $gw is not yet
   assigned in the caller, so the finally block cannot reap it -> orphan
   gateway holding the port for the next run.

2. create-fail scoring: a non-zero `sandbox create` exit alone is not proof
   of a policy rejection (gateway-registration/transport/fixture errors also
   exit non-zero and would false-pass). PASS now requires a genuine
   rejection signal (network / invalid_argument / network_policies) AND that
   it is not an infrastructure failure; other non-zero exits go to FAIL with
   output captured.

3. deny scenarios (ControlTarget path): snapshot the deny target AFTER
   Wait-File lands the control artifact, so a late denied write (enforcement
   regression racing the control write) can no longer be recorded as PASS.

4. -KeepRunning: break out of the scenario loop after the first scenario so
   a later scenario does not start a second gateway on the same port
   (previously a reliable port collision instead of a usable debug mode).

Re-verified PASS=4 FAIL=0 on both boxes (7F203-MXC-001 base-container and
7F203-MXC-003 AppContainer fallback); network-policy-rejected correctly
scores as "policy rejection".

Signed-off-by: Akber Raza <akberr@nvidia.com>
Mirror the sibling run-*.ps1 scripts by collecting every run's logs into a
timestamped results-e2e-<stamp>\ folder and zipping it. The bundle contains the
console transcript, per-scenario gateway stdout/stderr, the exact TOML rendered
for each scenario, the policy fixture used, and a summary.txt with the verdict
table.

Per-scenario gateway logs now land in gateway.<scenario>.log/.err.log inside the
bundle instead of a single fixed gateway.e2e.log in the script directory.

Wrap pre-flight, mode setup, scenario definitions, and the scenario loop in a
single try/catch/finally so the finally always writes the summary, stops the
transcript, and zips the bundle -- even on a pre-flight failure. The existing
per-scenario gateway-cleanup try/finally stays nested inside. All scenario
logic, scoring rules, and comments are preserved.

Signed-off-by: Prashant S Khodade <pkhodade@nvidia.com>
Signed-off-by: Akber Raza <akberr@nvidia.com>
- Require -Scenario when -KeepRunning: the loop breaks after the first
  scenario, so a full-suite run would execute only one scenario yet still
  report the suite as PASS. Fail fast so a partial run can't be mislabeled
  complete.
- Start-Transcript now runs inside the guarded try block with a
  $transcriptStarted flag; Stop-Transcript is only called when it actually
  started, so a Start-Transcript failure still yields the results bundle.
- Wrap the -Scenario filter in @() so a single exact match stays an array
  (reliable .Count and a proper array for the scenario loop on PS 5.1).

Signed-off-by: Prashant S Khodade <pkhodade@nvidia.com>
Signed-off-by: Akber Raza <akberr@nvidia.com>
…paced paths

Start-Process -ArgumentList does not quote array elements, so launching the
gateway with a bare --config <path> token split on any space in the install
path (e.g. C:\Users\First Last\...), and clap rejected the fragment with
'unrecognized subcommand'. Every MXC example launcher that started the gateway
hit this when the kit was unzipped under a path containing a space.

Pass the config path through the OPENSHELL_GATEWAY_CONFIG env var (which the
gateway already reads via clap) and drop the --config token. Env vars carry
spaces safely.

Affected: run-ocsf-audit, run-mxc-e2e, run-demo, run-inference-test,
run-ollama-test. run-mtls-test was not affected (its launch passes no config
path). Root-caused and fix-verified on 7F203-MXC-003 from a spaced path.

Signed-off-by: Akber Raza <akberr@nvidia.com>
Restore the proxy-enabled OCSF audit example removed by 13185f6 now that the host CONNECT proxy is present. Adapt the proxy lifecycle test to the target branch's DriverSandboxSpec policy delivery contract.

Signed-off-by: Akber Raza <akberr@nvidia.com>
- Share the per-sandbox public CA bundle with the AppContainer
- Add real wxc-exec HTTPS proxy coverage and document trust isolation

Signed-off-by: Akber Raza <akberr@nvidia.com>
- Reject middleware-bearing MXC policies before sandbox lifecycle begins
- Guard host proxy startup and document the unsupported registry path
- Add mapper, lifecycle, and host proxy regression coverage

Signed-off-by: Akber Raza <akberr@nvidia.com>
- remove obsolete inference routing from the host proxy adapter
- use the workspace AWS-LC provider in host-proxy tests
- adapt the forward-proxy test to ProxyIdentityMode

Signed-off-by: Akber Raza <akberr@nvidia.com>
Signed-off-by: Shailendra Singh <shailendras@nvidia.com>
Signed-off-by: Shailendra Singh <shailendras@nvidia.com>
- Introduced `pending_provider_credentials` in `MxcComputeBackend` to manage out-of-band provider credential state.
- Added `append_provider_child_env` function to merge provider credentials into the agent environment, ensuring sensitive values are not exposed.
- Updated `create_sandbox` method to validate egress requirements for provider credentials.
- Implemented `resolve_sandbox_create_runtime_inputs` to prepare driver-specific sandbox creation state, including effective policy and provider credentials.
- Modified gRPC handlers to utilize the new provider credential management features.
- Updated documentation to clarify the use of provider credentials and their requirements for governed egress.

Signed-off-by: Akber Raza <akberr@nvidia.com>
Add an end-to-end Windows MXC scenario for verifying provider credential
handling without exposing the raw credential to the sandbox.

The scenario confirms that the sandbox receives a revision-scoped
GITHUB_TOKEN placeholder, the host CONNECT proxy substitutes the credential
only for api.github.com, and use of the same placeholder against github.com
is rejected with credential_endpoint_mismatch.

Use inbox Windows PowerShell and curl for the probe so the standard Windows
build requires no additional test executable. Configure SystemRoot and
PATHEXT explicitly through agent_env, which provides the minimum environment
needed to locate and execute curl while avoiding implicit inheritance of the
gateway environment.

Add pc_disable_ui for process-container workloads that require Win32k during
startup. Preserve the hardened default and continue denying clipboard access
and input injection when UI compatibility is enabled.

Collect redacted diagnostic artifacts, check for raw-token leakage, and
document the MXC configuration and credential-validation workflow.

Tests:
- cargo test -p openshell-driver-mxc
- Windows PowerShell curl launch with only SystemRoot and PATHEXT

Signed-off-by: Akber Raza <akberr@nvidia.com>
- pass effective provider policy and credential state into MXC sandbox creation
- inject revision-scoped placeholders into the MXC child environment
- resolve provider credentials only through governed host CONNECT proxy requests
- add gateway and driver coverage for secret isolation and policy propagation
- update MXC documentation and remove obsolete provider-v2 test setup

Signed-off-by: Akber Raza <akberr@nvidia.com>
Align the driver configuration table with the canonical process_container default and isolation_session opt-in behavior.

Signed-off-by: Akber Raza <akberr@nvidia.com>
Clarify that the provider credential example uses process_container and does not require the isolation_session DLL or build feature.

Signed-off-by: Akber Raza <akberr@nvidia.com>
Mark the credential scenario failed and suppress its ZIP bundle when any result artifact cannot be inspected for raw-token leakage.

Signed-off-by: Akber Raza <akberr@nvidia.com>
Detect and redact a raw provider token before the credential probe result can reach console or CI logs.

Signed-off-by: Akber Raza <akberr@nvidia.com>
Derive provider layers, credential scopes, and binding records from the same loaded provider snapshot to eliminate cross-read inconsistency.

Signed-off-by: Akber Raza <akberr@nvidia.com>
Require workspace authorization before returning sandbox provider environment or credential binding data, while preserving sandbox-principal scope checks and not-found concealment.

Signed-off-by: Akber Raza <akberr@nvidia.com>
Fail sandbox creation for expiring static provider credentials because MXC has no live refresh channel, while retaining request-time dynamic token grants and documenting recreation requirements.

Signed-off-by: Akber Raza <akberr@nvidia.com>
Clarify that per-sandbox ports provide routing separation rather than peer authentication, place host-local processes in the trusted computing base, and retain M3 as the stronger source-attribution dependency.

Signed-off-by: Akber Raza <akberr@nvidia.com>
- preserve native JSON arguments under Windows PowerShell
- tolerate existing gateway registrations
- reject network executable paths with actionable launch diagnostics
- record redacted failure context in result bundles

Signed-off-by: Akber Raza <akberr@nvidia.com>
@copy-pr-bot

copy-pr-bot Bot commented Sep 12, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@araza008

Copy link
Copy Markdown
Contributor Author

I have read the DCO document and I hereby sign the DCO.

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.

4 participants