Repository navigation
[Seatbelt] network.proxy is enforced on LXC/Bubblewrap-0.8 but only cooperative on macOS Seatbelt #937
Description
Relevant area(s)
macOS
Brief description of your issue
network.proxy means different things on different backends, and on macOS Seatbelt a policy that looks enforced is only cooperative. LXC already established the project's position on this and fails closed — apply_firewall_rules refuses to run rather than report success for an enforcement that did not happen:
network.proxyrequiresnetwork.enforcementMode='firewall'or'both'. This policy enables a proxy under 'capabilities', where no iptables rules are installed, so the proxy environment would be injected while direct egress stayed unrestricted -- any client that ignoresHTTP_PROXYwould bypass the proxy entirely. Refusing to apply rather than reporting success for an enforcement that did not happen.
— src/backends/lxc/common/src/network_iptables.rs:1673-1682
Seatbelt accepts the same configuration and silently does the cooperative thing instead:
| Backend | Behavior with network.proxy |
|---|---|
| LXC | Enforced; fails closed if enforcement is unavailable |
| Bubblewrap, schema 0.8+ | Enforced (default-DROP + proxy allowlist in a private netns) |
| Bubblewrap, schema 0.6 / 0.7 | Cooperative — env vars only, shared host network |
| Seatbelt (macOS) | Cooperative — injects HTTP_PROXY/HTTPS_PROXY, and defaultPolicy: allow emits an unfiltered (allow network-outbound) |
Any client that ignores the proxy environment variables reaches the network directly, and the caller gets no signal that this is what they configured.
Bubblewrap 0.6/0.7 is a deliberate, documented concession for existing consumers on those schema versions and should be left as-is; it is listed here only for comparison. Seatbelt is the case that needs a decision.
This issue is about resolving the inconsistency, not about picking a specific answer up front. Reasonable outcomes differ — enforce it, reject the configuration the way LXC does, or accept it explicitly with the limitation documented and surfaced as a warning. What should not persist is the current state, where the same policy is silently enforced on one backend and advisory on another.
Source: adversarial review of #931 (Medium), where it was raised as a macOS-only gap.
Steps to reproduce
- Author a policy with
network.proxyset to a reachable proxy. - Run it under Seatbelt on macOS with a workload that makes an outbound connection without consulting
HTTP_PROXY— e.g. a raw TCP connect to a public address on port 443. - Run the equivalent policy under LXC with
enforcementModeleft at its default.
Expected behavior
Consistent, predictable handling across backends. A backend that cannot enforce the proxy should not accept the configuration silently; it should either reject it as LXC does, or surface an explicit warning stating that enforcement is cooperative and that non-cooperating clients will bypass the proxy. Whatever is chosen should be reflected in docs/schema.md and docs/macos-support/seatbelt-backend.md.
Actual behavior
The direct connection succeeds under Seatbelt, bypassing the proxy, with no error or warning. The same shape of policy is refused outright by LXC. Callers writing one policy for multiple backends have no way to tell which are enforcing it.
The WSLc half of this issue was split out into its own tracking item, since it is blocked on the WSLc SDK rather than on a decision.
Related: #946 — the no-proxy path on the same backend, where allowedHosts under defaultPolicy: "block" degrades to allow-all outbound.
Activity
github-actions commentedon Aug 18, 2026
Triage complete.
Labels added:
Container-WSLC,Area-Executor-LXC(OS labelsOS-Linux,OS-MacOS,OS-Windowswere already present).Owners assigned:
@richiemsft(macOS/Seatbelt),@bbonaby(networking/proxy/firewall), joining the already-assigned Soham Das (@SohamDas2021) (LXC/Bubblewrap/WSLc) and@theelliotm.Needs-Triageremoved.Maintainers: Comment
/investigateto check whether this issue or bug is valid against the most current code. Copilot will also produce a report with the changes that will be needed. For a small, unambiguous documentation or test fix, it may also create one draft PR.theelliotm commentedon Aug 18, 2026
Which is preferable: always blocking an "allow + proxy" schema or warning loudly?
SohamDas2021 commentedon Aug 18, 2026
Note that WSLC is blocked on WSLC SDK support. So this bug only applies to seatbelt for now.
[-][Cross-backend] network.proxy is enforced on LXC/Bubblewrap-0.8 but only cooperative on Seatbelt and WSLc[/-][+][Seatbelt] network.proxy is enforced on LXC/Bubblewrap-0.8 but only cooperative on macOS Seatbelt[/+]SohamDas2021 commentedon Aug 19, 2026
Split: the WSLc half of this issue now lives in #947, since it is blocked on the WSLc SDK (no
CAP_NET_ADMIN, no VM-level enforcement hook) rather than on a design decision. This issue is now Seatbelt-only.github-actions commentedon Aug 19, 2026
Triage complete.
Labels added:
Container-Process(Seatbelt is the macOS process container backend; existingOS-MacOS,OS-Linux, andArea-Executor-LXClabels were already present and correct).Owner assigned:
@richiemsft(macOS / Seatbelt backend).@theelliotmwas already assigned.Needs-Triagehas been removed.Maintainers: Comment
/investigateto check whether this issue or bug is valid against the most current code. Copilot will also produce a report with the changes that will be needed. For a small, unambiguous documentation or test fix, it may also create one draft PR.