Skip to content

[Bubblewrap/LXC] Address network policy gaps - schema#634

Open
dhoehna wants to merge 6 commits into
microsoft:mainfrom
dhoehna:user/dahoehna/lxc-net-schema-migration
Open

[Bubblewrap/LXC] Address network policy gaps - schema#634
dhoehna wants to merge 6 commits into
microsoft:mainfrom
dhoehna:user/dahoehna/lxc-net-schema-migration

Conversation

@dhoehna

@dhoehna dhoehna commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Linked work item: AB#62830582 — [Bubblewrap/LXC] Address network policy gaps - schema

Summary

Adds the GA network policy schema and migration for LXC/Bubblewrap.

  • New wire schema under network: egress.{allow,deny}[] (each to: [{ cidr }], ports: [{ protocol, port }]), ingress.hostLoopback, and proxy.http.
  • Parser maps GA config to the internal model: ingress.hostLoopbackallow_local_network, proxy.httpnetwork_proxy, egress.* → internal EgressRules.
  • CIDR-only: every destination is validated with std::net; DNS hostnames are rejected with a clear parse error.
  • Legacy allowedHosts / blockedHosts / defaultPolicy continue to work. Precedence: GA network.egress supersedes the legacy list fields; ingress.hostLoopback overrides allowLocalNetwork.
  • Added GA SDK policy types; regenerated JSON schema + TS wire types.

Model

  • Adds EgressRule, Protocol, RuleAction to wxc_common::models.

Validation

  • cargo fmt --all -- --check; cargo clippy -p wxc_common -D warnings — clean
  • cargo test -p wxc_common — 403 passed; cargo test -p mxc-sdk — 23 passed
  • cargo check --target x86_64-unknown-linux-gnu -p wxc_common — pass

Coupling

The internal EgressRule / Protocol / RuleAction types are also added independently by the enforcement PRs (AB#62830559, AB#62830341). This PR owns the JSON parser; the enforcement PRs consume the model field. Merge-time reconciliation is expected.

Microsoft Reviewers: Open in CodeFlow

Copilot AI review requested due to automatic review settings July 10, 2026 22:56
@dhoehna
dhoehna requested a review from a team as a code owner July 10, 2026 22:56

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.

Pull request overview

This PR extends MXC’s network configuration surface with a GA schema for LXC/Bubblewrap, adding structured egress/ingress policy and an HTTP proxy field, then wiring that schema through the Rust wire model → parser → internal policy model and the SDK policy layer (including regenerated schema + TS wire types).

Changes:

  • Added GA network.egress (allow/deny rules), network.ingress.hostLoopback, and network.proxy.http to the Rust wire model and dev JSON schema.
  • Mapped GA network fields in config_parser into new internal EgressRule/Protocol/RuleAction model fields with validation (CIDR-only destinations).
  • Updated SDK policy mapping + tests and regenerated sdk/src/generated/wire.ts.

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/core/wxc_common/src/wire.rs Adds GA network wire schema structs/enums (egress/ingress/proxy.http).
src/core/wxc_common/src/models.rs Introduces internal egress rule model types and stores them on ContainerPolicy.
src/core/wxc_common/src/config_parser.rs Parses/validates GA network fields and maps them into the internal model with legacy precedence rules.
src/core/mxc-sdk/tests/sdk_helpers.rs Adjusts test helper construction for the expanded network policy struct.
src/core/mxc-sdk/src/policy.rs Adds SDK GA network policy types and emits GA schema in wire config when present.
sdk/src/generated/wire.ts Regenerated TS wire types to include the new GA network schema.
schemas/dev/mxc-config.schema.0.8.0-dev.json Regenerated dev JSON schema with GA network types and fields.

Comment thread src/core/wxc_common/src/config_parser.rs Outdated
…nly (AB#62830582)

- Add GA network schema (egress.allow/deny with cidr+ports+protocol, ingress.hostLoopback, proxy.http) to wire + parser + internal EgressRule model + SDK types.

- Reject DNS names (CIDR-only); keep legacy allowedHosts/blockedHosts/defaultPolicy working.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 3b78bec0-e139-4cfd-9c10-092ef986d4f4
@dhoehna
dhoehna force-pushed the user/dahoehna/lxc-net-schema-migration branch from 6108846 to f86ebb1 Compare July 13, 2026 16:45
…col (AB#62830582)

convert_wire_egress_rules pushed each GA port selector's port and protocol into
two independent Vecs on one EgressRule. Since the internal EgressRule treats
protocols x ports as a cartesian grid, a rule mixing selectors (e.g. tcp/80 +
udp/53) widened to also permit tcp/53 and udp/80.

Group selectors by protocol (first-seen order, deduped ports) and emit one
EgressRule per protocol group so each rule's cartesian expansion equals exactly
the requested selectors. Adds a regression test.

Addresses copilot-pull-request-reviewer feedback on PR microsoft#634.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread src/core/wxc_common/src/wire.rs Outdated
Comment thread src/core/wxc_common/src/wire.rs
Comment thread src/core/wxc_common/src/config_parser.rs Outdated
/// Proxy URL (parsed into host:port).
pub url: Option<String>,
/// GA HTTP proxy URL (parsed into host:port).
pub http: Option<String>,

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.

The GA spec puts the proxy in runtimeConfig.networkProxy (a URL, outside the network policy block), not network.proxy.http, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks — I'd like to defer the runtimeConfig.networkProxy relocation to a follow-up rather than fold it into this PR. Two reasons:

  1. Scope / risk. There is no runtimeConfig section anywhere in the wire model today, so this introduces a brand-new top-level config surface that is cross-cutting — schema, SDK public types, generated wire types, and every backend's proxy handling. That is meaningfully broader than this PR's "network policy schema" scope.
  2. Spec fidelity. Doing it correctly needs the canonical GA runtimeConfig.networkProxy spec (exact shape, precedence vs. the existing network.proxy, and which backends honor it). I don't want to guess the shape and bake in something we then have to break.

This PR intentionally leaves the existing network.proxy.http surface unchanged. I'll open a tracking issue for the runtimeConfig.networkProxy migration and link it here. If you have a link to the GA spec you'd like followed, I'm happy to do the relocation in a dedicated follow-up PR.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Tracking issue filed: #655 — I'll do the runtimeConfig.networkProxy relocation there in a dedicated follow-up (it needs the canonical GA spec for the exact shape and precedence vs. the existing network.proxy, plus it touches a new top-level runtimeConfig surface across schema, SDK types, generated wire types, and every backend). This PR intentionally leaves network.proxy.http unchanged. Leaving this thread open as the pointer to #655.

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.

I would block on this. Let's get the schema finalized at once and not check in temporary incorrect shapes.

Comment thread src/core/wxc_common/src/config_parser.rs
@microsoft-github-policy-service microsoft-github-policy-service Bot added the Needs-Author-Feedback Issue needs attention from issue or PR author label Jul 14, 2026
Implements the actionable reviewer feedback on the GA egress/proxy schema:

- ICMP has no ports: make EgressPort.port optional and reject a port
  paired with protocol 'icmp' (wire.rs, config_parser.rs).
- Add egress.default (allow|deny): lets the 'allow-all-except-deny-list'
  model be expressed and prevents a legacy defaultPolicy:'allow' from being
  silently downgraded when GA egress is present. Maps to the internal
  default_network_policy; omitted/deny fail closed (wire.rs, config_parser.rs).
- Optional rule ports: an omitted/empty ports list now means match-all
  (all ports and all protocols) to the listed destinations, so 'allow all
  ports to X' is expressible. A portless tcp/udp selector matches all ports
  for that protocol (config_parser.rs).
- Make the external-proxy + egress rejection backend-agnostic instead of
  Bubblewrap-only, since MXC never forwards egress rules to a proxy
  (config_parser.rs).

Regenerates the dev JSON schema and SDK wire types from the wire model,
updates the hand-written SDK public types (types.ts) and the mxc-sdk policy
port, and adds/updates unit tests. The proxy-placement thread
(runtimeConfig.networkProxy) is deferred and answered on the PR.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@microsoft-github-policy-service microsoft-github-policy-service Bot added Needs-Attention Issue needs attention from Microsoft and removed Needs-Author-Feedback Issue needs attention from issue or PR author labels Jul 14, 2026
dhoehna and others added 2 commits July 15, 2026 11:38
…s.json)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e5d2aa5b-7f04-4e4d-83d3-a02efe7020ab
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e5d2aa5b-7f04-4e4d-83d3-a02efe7020ab
@dhoehna

dhoehna commented Jul 17, 2026

Copy link
Copy Markdown
Contributor Author

🧪 Local test re-verification — 2026-07-17

Re-ran the test suites locally at branch tip 66c65d6 on a dev workstation. All green (0 failures).

Windows host (x86_64-pc-windows-msvc, cargo 1.96.1):

  • cargo test -p wxc_common409 passed, 0 failed
  • cargo test -p mxc-sdk11 passed, 0 failed (+4 runtime-ignored — require an elevated, host-prepped Windows host per docs/host-prep.md)

Linux (WSL2 Ubuntu-24.04, x86_64-unknown-linux-gnu, cargo 1.97.0, isolated CARGO_TARGET_DIR):

  • cargo test -p lxc_common39 passed, 0 failed — the workspace Linux crate also builds and passes.

Note: the wxc_common count differs slightly from the original Validation because the branch advanced since it was written.

lxc_common is unchanged by this PR; this PR's schema/parser changes are exercised by the wxc_common + mxc-sdk suites above.

@dhoehna

dhoehna commented Jul 20, 2026

Copy link
Copy Markdown
Contributor Author

@SohamDas2021 — every item from your review has been addressed and pushed; requesting a re-review.

Resolved (in 70c94d6; the Copilot selector item in 269909d):

  • ICMP has no ports — EgressPortWire.port is now Option<u16> and a port paired with protocol: "icmp" is rejected with a clear message (thread r3581216215).
  • Missing egress.defaultnetwork.egress now accepts default: allow|deny, mapped to the internal default_network_policy (fail-closed when omitted), so defaultPolicy: "allow" is no longer silently downgraded (thread r3581235209).
  • ports should be optional (match-all) — omitted/empty ports now means all ports/protocols to the destination; a portless tcp/udp selector matches all ports for that protocol (thread r3581245979).
  • Proxy + egress rejection should be backend-agnostic — the check moved into convert_wire_config and now runs for all backends, not just Bubblewrap (thread r3581281785).
  • Egress selectors cartesian-widened (Copilot) — selectors are now grouped into one internal EgressRule per protocol, so tcp/80 + udp/53 no longer permits tcp/53 (thread r3562427462).

Deferred (tracked in #655):

Validation @ 66c65d6: CI green (20/20 checks). Re-verified locally on this branch tip: cargo test -p wxc_common -> 409 passed, 0 failed; cargo test -p mxc-sdk -> green, 0 failed (streaming test ignored — needs an elevated, host-prepped Windows host).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Needs-Attention Issue needs attention from Microsoft

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants