@@ -227,6 +227,66 @@ no separate `--setup-wslc` step is required.
227227| ` "allowOutbound": true ` | Bridged networking (full access) |
228228| ` "allowOutbound": false ` | No networking (isolated) |
229229
230+ ### Network proxy (cooperative, unprivileged)
231+
232+ WSLC supports a ** cooperative HTTP/HTTPS proxy** : setting ` network.proxy `
233+ routes a container's egress through a proxy you provide. WSLC's kernel has
234+ ** no in-kernel ` iptables ` ** , so — exactly like the Bubblewrap backend — there
235+ is no netfilter drop-floor; enforcement is * cooperative* , applied by handing
236+ the workload proxy environment variables that well-behaved clients honor.
237+
238+ ** How it works**
239+
240+ 1 . When ` network.proxy ` is set, the runner translates it into the
241+ ` HTTP_PROXY ` , ` HTTPS_PROXY ` , ` http_proxy ` , and ` https_proxy ` environment
242+ variables inside the container (via ` WslcSetProcessSettingsEnvVariables ` ).
243+ Any caller-supplied values for these keys — including ` NO_PROXY ` /
244+ ` no_proxy ` — are ** stripped** from the * initial* process environment first.
245+ Because WSLC merges the process environment onto the image's baked-in
246+ ` ENV ` , the runner also sets ` NO_PROXY ` / ` no_proxy ` to the ** empty string** ,
247+ so an image-baked exemption (e.g. ` ENV NO_PROXY=* ` ) cannot silently disable
248+ the proxy. This sanitizes the process's * starting* environment only; see the
249+ cooperative-model caveat below.
250+ 2 . Cooperative tools (curl, wget, Python ` requests ` , Node ` https ` , etc.) honor
251+ the env vars and their traffic flows through the proxy.
252+
253+ ** Only the ` url ` form is supported.** A WSLC container runs in its own network
254+ namespace (a separate WSL system VM), so a host- or distro-loopback proxy is
255+ ** not reachable** from inside the container. The proxy must be a routable
256+ address the container can reach:
257+
258+ ``` json
259+ {
260+ "version" : " 0.6.0-alpha" ,
261+ "containment" : " wslc" ,
262+ "process" : { "commandLine" : " curl -fsSL https://example.com && echo OK" },
263+ "network" : {
264+ "defaultPolicy" : " allow" ,
265+ "proxy" : { "url" : " http://proxy.example:8080" }
266+ },
267+ "experimental" : { "wslc" : { "image" : " alpine:latest" } }
268+ }
269+ ```
270+
271+ The ` localhost ` and ` builtinTestServer ` proxy forms are ** rejected at
272+ config-parse time** for WSLC (they imply a host-loopback / MXC-run proxy that
273+ the container cannot reach). The proxy also requires ` defaultPolicy: "allow" `
274+ and no ` allowedHosts ` / ` blockedHosts ` : the container must have outbound
275+ networking to reach the proxy, and host lists are not forwarded to it — configs
276+ that combine the proxy with a ` block ` default or host lists are ** rejected** .
277+
278+ ** Caveats**
279+
280+ - ** Cooperative model, not enforcement.** Only clients that honor the proxy
281+ env vars are routed through the proxy. Tools that bypass them (raw sockets,
282+ custom HTTP clients, statically-linked binaries that ignore the env) are
283+ ** not** contained. WSLC cannot provide a hard network floor because its
284+ kernel lacks ` iptables ` . For strict network isolation, use
285+ ` "allowOutbound": false ` (no networking) instead.
286+ - ** Consumer-provided proxy.** MXC does not start a proxy for WSLC; you supply
287+ a reachable one via ` url ` . Any host filtering is the proxy's responsibility —
288+ the runner does not forward ` allowedHosts ` / ` blockedHosts ` to it.
289+
230290### Filesystem mounts
231291
232292Paths in ` filesystem.readwritePaths ` and ` filesystem.readonlyPaths ` are mounted
@@ -249,6 +309,7 @@ the container.
249309
250310- [ ` tests/examples/wslc_hello_world.json ` ] ( ../../tests/examples/wslc_hello_world.json ) — Hello world with Alpine
251311- [ ` tests/configs/wslc_network_isolated.json ` ] ( ../../tests/configs/wslc_network_isolated.json ) — Network isolation
312+ - [ ` tests/configs/wslc_network_proxy.json ` ] ( ../../tests/configs/wslc_network_proxy.json ) — Cooperative HTTP proxy (` network.proxy.url ` )
252313- [ ` tests/configs/wslc_custom_registry_ghcr.json ` ] ( ../../tests/configs/wslc_custom_registry_ghcr.json ) — Pull from GitHub Container Registry
253314- [ ` tests/configs/wslc_custom_registry_quay.json ` ] ( ../../tests/configs/wslc_custom_registry_quay.json ) — Pull from Quay.io
254315- [ ` tests/configs/wslc_tar_import_rootfs.json ` ] ( ../../tests/configs/wslc_tar_import_rootfs.json ) — Import rootfs tar
0 commit comments