Skip to content

Fix ProcessContainer host-loopback compatibility on PSEC 1.0 - #1490

Merged
Branden Bonaby (bbonaby) merged 8 commits into
mainfrom
user/bbonaby/fix-psec-1-0-issue
Oct 16, 2026
Merged

Branden Bonaby (bbonaby) merged 8 commits into
mainfrom
user/bbonaby/fix-psec-1-0-issue

Conversation

@bbonaby

@bbonaby Branden Bonaby (bbonaby) commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

📖 Description

  • Allow BaseContainer to reach host services over loopback on PSEC 1.0 and newer hosts when hostLoopback: allow and the egress policy permit it, including when ingress is denied by default.
  • Use the loopback behavior provided by the Windows build. Native ingress support adds two-way access and allows the container to host a loopback server.
  • Keep proxy traffic restricted to the configured endpoint, and preserve filesystem version requirements and networking defaults.
  • Clarify the discovery flag descriptions and cover direct access and proxy isolation in the tests.

🔗 References

Closes #1485.

🔍 Validation

  • VM validation reported passed on PSEC 1.0, PSEC 1.1 with native ingress, and PSEC 1.1 with networkIngress disabled. The suites cover direct access with both ingress defaults and proxy endpoint isolation using separate IPv4 and IPv6 listeners.

Commands run from src/:

  • cargo fmt --all -- --check - passed.
  • cargo test -p mxc-sdk --lib -- psec_ loopback_and_proxy identityless_loopback_proxy runtime_proxy_uses_peer identity_scoped_proxy process_container::common::probe::tests:: mxc_engine::probe::tests:: - passed: 50 tests.
  • cargo clippy -p mxc-sdk --lib --tests -- -D warnings with CARGO_INCREMENTAL=0 - passed.
  • cargo build -p wxc -p plm -p wxc_winhttp_proxy_shim - passed.
  • $env:RUSTDOCFLAGS='-D rustdoc::broken_intra_doc_links'; cargo doc -p mxc-sdk --no-deps --lib - failed on existing broken links in unchanged documentation; not rerun.

From sdk/node/, npm run typecheck - passed. Full .NET and Node test suites were not run; their changes are documentation-only.

✅ Checklist

📋 Issue Type

  • Bug fix
  • Feature
  • Task

GitHub Actions runs the PR validation build automatically. The ADO pipeline
(MXC-PR-Build) is the Azure version of the PR pipeline, kept in parity with the GitHub
Actions build; it runs on merge to main, and Microsoft reviewers with write access can trigger it
on a PR with /azp run. See pull request builds.

If the dependency-feed-check check fails on a new dependency, the crate must be added to
the feed before the PR can pass. See pull request builds
for the steps.

Microsoft Reviewers: Open in CodeFlow

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: fa1ea5a5-f8e6-4a00-9b94-a8b0192e3466
Copilot AI balanced review requested due to automatic review settings October 13, 2026 22:32
@bbonaby
Branden Bonaby (bbonaby) requested a review from a team as a code owner October 13, 2026 22:32
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Direct PSEC 1.0 requests omit the capability needed for loopback connectivity, and the updated tests depend on host capabilities.

1 open finding
What changed in this PR

Updates ProcessContainer host-loopback compatibility for PSEC 1.0 hosts.

Changes:

  • Selects PSEC 1.1 only when ingress support is advertised.
  • Removes the identity-less proxy-only workaround.
  • Updates PSEC version-selection and encoding tests.
File Description
src/​mxc-sdk/​src/​backends/​process_container/​common/​base_container_runner.rs Revises host-loopback serviceability and PSEC selection.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/mxc-sdk/src/backends/process_container/common/base_container_runner.rs Outdated
Verify direct and identity-less proxy loopback access, avoid shell-launch false positives, and document Windows build support. Make loopback unit tests independent of host ingress support.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: fa1ea5a5-f8e6-4a00-9b94-a8b0192e3466
Copilot AI balanced review requested due to automatic review settings October 13, 2026 22:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The proxy test mishandles blocked DNS, selector coverage is incomplete, and the documented bidirectional contract is ambiguous.

4 open findings

🧠 Review effort: Balanced

Comment thread src/mxc-sdk/src/backends/process_container/common/base_container_runner.rs Outdated
Comment thread tests/scripts/run_processcontainer_network_proxy_test.ps1 Outdated
Comment thread docs/backends/process-container/networking.md Outdated
Name the direct loopback validation area explicitly while preserving its previous selector as an alias. Accept policy-blocked DNS in proxy egress checks and clarify Windows build-dependent loopback support.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: fa1ea5a5-f8e6-4a00-9b94-a8b0192e3466
Copilot AI balanced review requested due to automatic review settings October 13, 2026 23:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The PSEC 1.0 direct path omits a required capability, and discovery no longer matches runtime proxy support.

4 open findings
1 resolved since last review

🧠 Review effort: Balanced

Comment thread src/mxc-sdk/src/backends/process_container/common/base_container_runner.rs Outdated
Add the loopback capability alongside the peer for direct requests when native ingress support is unavailable. Cover allow and deny encoding independently of host capabilities and document the compatibility mapping.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: fa1ea5a5-f8e6-4a00-9b94-a8b0192e3466
Copilot AI balanced review requested due to automatic review settings October 13, 2026 23:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The fallback can incorrectly treat unsupported PSEC 1.1 hosts or capability-query failures as PSEC 1.0-compatible.

4 open findings
1 resolved since last review

🧠 Review effort: Balanced

Comment thread src/mxc-sdk/src/backends/process_container/common/base_container_runner.rs Outdated
Comment thread tests/scripts/run_processcontainer_network_proxy_test.ps1
Always grant networkLoopback when host loopback is allowed. Preserve ingress-query failures, align proxy discovery with compatible PSEC support, and strengthen version-selection and loopback endpoint regressions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: bfb39885-bfc3-4c08-911e-c98dc5daa379
Copilot AI balanced review requested due to automatic review settings October 14, 2026 23:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Windows-native network enforcement changes require final platform review across supported host builds.

0 open findings

4 resolved since last review

🧠 Review effort: Balanced

Keep proxy discovery and examples focused on caller requirements, and describe the validation expectations in plain language.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: bfb39885-bfc3-4c08-911e-c98dc5daa379
Copilot AI balanced review requested due to automatic review settings October 15, 2026 03:09

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Windows-build-dependent network-isolation changes warrant platform-owner confirmation of the reported cross-version validation.

0 open findings

🧠 Review effort: Balanced

@MGudgin Gudge (MGudgin) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the current PR changes against head ce040460c (merge-base e492072a3). The two comments below ask for coverage of newly supported network-policy combinations; neither asserts a demonstrated WFP bypass or a broken current host. The version selector now tests both ingress-support values, ingress-query errors are surfaced, and the proxy test checks a second host-reachable endpoint. No unrelated pre-existing findings are attributed to this PR.

(true, false, false, true),
(true, true, true, true),
(true, true, false, false),
(true, true, false, true),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium (test coverage) — exercise the newly supported PSEC 1.1/no-ingress proxy host state.

Attribution: introduced_by_change — this new matrix case treats a host supporting both PSEC 1.0 and 1.1, but not advertising native network ingress, as identity-less-proxy-capable. The selector/discovery tests use synthetic support values; the reported live runs cover a PSEC 1.0 machine and a PSEC 1.1 machine with ingress support, not this combination.

Could you validate the precise combination on a host that reports PSEC 1.1 available and network ingress absent, with proxy support enabled? In particular, check that the workload reaches the configured proxy and cannot connect directly to the separate host-reachable loopback listener. If the combination cannot be staged, please note that validation gap. This is not a claim that proxy containment is currently bypassed.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The live suite passed on a PSEC 1.1 machine with networkIngress disabled. It reached the configured proxy and blocked direct connections to the other IPv4 and IPv6 listeners.

#[test]
fn psec_direct_host_loopback_encodes_capability_and_peer_regardless_of_ingress_support() {
let mut request = host_loopback_request();
request.policy.network_egress = Some(crate::mxc_common::models::NetworkEgressPolicy {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium (test coverage) — exercise direct PSEC 1.0 loopback with a deny-default ingress policy.

Attribution: introduced_by_change — the new direct compatibility-path encoding test uses host_loopback_request() (ingress.default: allow) and sets egress.default: allow; the live direct-loopback check uses the same defaults. Neither establishes whether the newly accepted PSEC 1.0 request works with ingress.default: deny, hostLoopback: allow, egress.default: allow, and no proxy. That shape omits privateNetworkClientServer while retaining the explicit loopback grant.

Could you add an encoding assertion for the expected capability/peer combination and a PSEC 1.0 live check that the container reaches a medium-integrity host listener on BaseContainer, or reject/document the narrower shape if it cannot be supported? Please do not infer from this comment that egress.default: deny must also reach the listener; that is a separate policy question.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this case to both the encoding test and live suite. With ingress denied by default, egress allowed, and host loopback allowed, the PSEC 1.0 run reached the host listener without a proxy.

@MGudgin Gudge (MGudgin) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requested changes — PR #1490 at ce040460c

The new direct-loopback path and the proxy-discovery update are coherent on the modeled hosts. I am requesting changes primarily for two PR-attributable issues: the new fallible ingress query can reject an otherwise viable non-loopback request, and the positive PSEC 1.0 live test does not control the host listener's integrity level on an elevated CI runner. See the inline comments for those and for the public discovery wording and newly relevant IPv6 test gap.

Coverage requests already posted

  • Medium — narrower direct policy (introduced_by_change): the new tests use ingress.default: allow and egress.default: allow; they do not establish PSEC 1.0 connectivity with ingress.default: deny, hostLoopback: allow, and egress allowed. This was posted in the existing inline thread; I am not filing it twice.
  • Medium — ingress-disabled PSEC 1.1 proxy host (newly_exposed_by_change): the PR newly admits the PSEC 1.0 proxy mapping on a 1.1-capable host without native ingress, but synthetic support-matrix tests do not establish launch and endpoint confinement on that host state. This was posted in the existing inline thread. The new inline comment below adds the distinct missing native-creation/IPv6 test coverage.

Advisory, not a merge condition

  • Low — partial-service diagnostics (introduced_by_change): src/mxc-sdk/src/backends/process_container/common/base_container_runner.rs:508-565 logs the selected PSEC version but not the PSEC 1.0 host-loopback limitation when hostLoopback: allow is accepted. A request-aware probe warning or explicit runtime log would make failed in-container-listener/low-integrity connections easier to diagnose. This limitation is documented in the PR, so I do not treat the missing warning as a correctness defect.

Verified clean and pre-existing context

  • The new networkLoopback capability remains conditional on explicit host-loopback allow; deny/omitted encoding tests cover both. The proxy-mode negative test requires a real curl connection failure to a second host-reachable IPv4 endpoint. Version-selection unit tests now exercise both ingress support values. These checks do not replace live coverage of the untested host states.
  • docs/schema.md and the released stable schema's generic bidirectional identity-less-proxy descriptions are byte-identical to the base, and PSEC 1.0 identity-less proxies already existed before this PR. Those pre-existing statements are not attributed to this change or conditions of this review. The stale generic fallback error for other policy-incompatibility causes is likewise not charged to this PR.

Attribution was checked against the three-dot PR diff (merge-base e492072a3, recorded base ref 2366ee9b1) and head ce040460c. No new local test run or unsupported host-state validation is claimed.

Comment thread src/mxc-sdk/src/backends/process_container/common/base_container_runner.rs Outdated

/// Whether BaseContainer can enforce
/// `network.ingress.hostLoopback = "allow"`.
/// Whether BaseContainer supports native bidirectional host-loopback ingress.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium (documentation drift) — carry this native-only qualification through public discovery docs.

Attribution: newly_exposed_by_change — direct hostLoopback: allow is now serviceable on PSEC 1.0 even though the IngressHostLoopbackAllow fact is false there. This revised runner comment correctly calls the fact native bidirectional support, but unchanged consumer-facing descriptions in src/mxc-sdk/src/core/mxc_engine/probe.rs:29-30, src/mxc-sdk/src/backends/process_container/common/probe.rs:74-76, and the .NET V1 PlatformDiscovery.cs enum still read as generic host-loopback allow enforcement at the tier. Clients using the flag as an all-or-nothing preflight can suppress this PR's newly supported direct request.

Fix: Define the fact consistently as full native ingress in the published Rust/.NET/Node references, and point callers to the request-aware probe for PSEC 1.0's narrower serviceable mode. I am not asking to change an immutable released schema.

@bbonaby Branden Bonaby (bbonaby) Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the existing Rust, .NET, and Node descriptions

-EgressDefault 'deny' -IngressDefault 'allow' -HostLoopback 'allow' `
-NetworkProxy $proxyUrl -TimeoutMs 25000
$loopback = Invoke-NetRun -Name 'net-proxy-direct-loopback-blocked' -ConfigPath $cfgLoopback
Record-Result -Phase 'P8e' -Name 'direct access to a second loopback endpoint is blocked' `

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium (test coverage) — also exercise native acceptance and IPv6 endpoint isolation without ingress.

Attribution: newly_exposed_by_change — the PR admits identity-less proxy requests on PSEC 1.1-capable hosts with ingress disabled, selecting a PSEC 1.0 payload. This new second-listener check covers an IPv4 endpoint; existing Rust OS-creation/launch and ::1 bypass tests in base_container_helpers/tests.rs skip when supports_ingress_host_loopback_allow() is false and construct only V1.1/ingress-enabled specs. The old PSEC 1.0-only proxy workaround predated this PR; the additional 1.1-without-ingress host state is what makes the gap newly relevant.

Fix: Run native create/launch and both IPv4 and IPv6 confinement checks with the V1.0 mapping on the newly supported host state, or add an equivalent ::1 negative assertion to the live proxy test. The separate missing-host-state validation is already in an earlier review thread.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The native create and launch tests now use PSEC 1.0 and no longer require ingress support. The live suite also checks a separate IPv6 listener, and it passed with networkIngress disabled.

-Pass (Test-SelectedTier $allow.Log) `
-Detail "selectedTier=$(Get-SelectedTier $allow.Log); expected=base-container"
Record-Result -Phase 'P8d' -Name 'hostLoopback=allow without a runtime proxy reaches the host loopback anchor' `
-Pass (($allow.Result.Stdout.Trim() -eq 'MXC-LOOPBACK-ANCHOR') -and ($allow.Result.ExitCode -eq 0) -and -not $allow.Result.TimedOut) `

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium (Windows build/CI parity) — use a controlled medium-integrity host listener.

Attribution: newly_exposed_by_change — this positive assertion now requires success on PSEC 1.0-only hosts, where the PR specifies support for medium-integrity host listeners only. Start-LoopbackListener binds the listener in the harness process/runspace (WinProcessContainer.Common.ps1:1020-1052); the CI guide says the 1ES agent runs elevated. On an elevated older-host runner the listener inherits the higher-integrity token, so this test can fail while the documented medium-integrity compatibility behavior works correctly. A host-side Invoke-WebRequest prerequisite proves reachability, not listener integrity.

Fix: Run the positive listener under a verified medium-integrity token (or lower the listener helper's token), then assert the container reaches it. Keep separate tests for other listener integrity levels with their own expected outcomes.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kept the listener in the test process. It is a normal host process, not another AppContainer that needs its own loopback access, so forcing it to medium integrity is not required.

@microsoft-github-policy-service microsoft-github-policy-service Bot added the Needs-Author-Feedback Waiting for additional information or action from the issue or pull-request author. label Oct 15, 2026
)?
} else {
false
};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wrong - we don't evaluate support here.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please elaborate. Do you mean 'mxc does not/should not evaluate what the underlying platform does or does not support/have enabled'? Or 'this check should be done elsewhere in mxc'?

@bbonaby Branden Bonaby (bbonaby) Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I no longer do the checks in this. We request loopback access and let Windows provide the behavior supported by that build.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🕐

Use the loopback behavior available on each Windows build, preserve proxy endpoint restrictions, and align discovery descriptions and regression coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: bfb39885-bfc3-4c08-911e-c98dc5daa379
Copilot AI balanced review requested due to automatic review settings October 16, 2026 05:52
@microsoft-github-policy-service microsoft-github-policy-service Bot added Needs-Attention Requires attention or a decision from the MXC maintainers. and removed Needs-Author-Feedback Waiting for additional information or action from the issue or pull-request author. labels Oct 16, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Security-sensitive Windows networking still needs live validation of the remaining configurations, and a native-test synchronization issue remains unresolved.

1 open finding

🧠 Review effort: Balanced

Comment on lines +86 to +88
if !BaseContainerRunner::supports_identityless_loopback_proxy()
.expect("query identity-less loopback proxy support")
{

// Temporary compatibility for explicit identity-less proxies on PSEC 1.0-only
// hosts. Remove once those hosts support PSEC 1.1; keep loopback allow opt-in.
fn psec_1_0_proxy_loopback_workaround(

@bbonaby Branden Bonaby (bbonaby) Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: with my change this proxy work around for machines with PSEC 1.0 that used unpackaged medium IL proxies is no longer needed as my change is general and will allow for this scenario, as it only needed us to pass in the "networkLoopback" capability.

@bbonaby
Branden Bonaby (bbonaby) dismissed stale reviews from Gudge (MGudgin) and Jeff Whiteside (jsidewhite) October 16, 2026 17:51

updated per comments, I believe I've addressed what we discussed. Also need to unblock openAI.

@bbonaby
Branden Bonaby (bbonaby) merged commit b211201 into main Oct 16, 2026
31 checks passed
@bbonaby
Branden Bonaby (bbonaby) deleted the user/bbonaby/fix-psec-1-0-issue branch October 16, 2026 18:46
@microsoft-github-policy-service microsoft-github-policy-service Bot removed the Needs-Attention Requires attention or a decision from the MXC maintainers. label Oct 16, 2026
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.

MXC 1.0 rejects host-loopback policies that worked in 0.8 on PSEC 1.0 hosts

6 participants