Skip to content

feat(sandbox): support network_policy in the OpenSandbox provider - #2407

Draft
terrykong wants to merge 1 commit into
terryk/sandbox-task-hooksfrom
terryk/sandbox-network-policy
Draft

feat(sandbox): support network_policy in the OpenSandbox provider#2407
terrykong wants to merge 1 commit into
terryk/sandbox-task-hooksfrom
terryk/sandbox-network-policy

Conversation

@terrykong

@terrykong terrykong commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

PR 4 of 5 in the gym sandbox debug stack (#2400#2401#2402#2407#2403).

Why

The provider had no way to send a networkPolicy, and provider_options rejects unknown keys, so this was not something a caller could work around.

That matters more than "one unsupported field" suggests. Server-side, apply_egress_to_spec returns early when no policy is present, so the egress sidecar is never attached at all. In practice no egress feature was reachable from Gym — not filtering, not the credential proxy, not transparent MITM.

SandboxSpec(
    image=...,
    provider_options={"network_policy": {"defaultAction": "allow", "egress": []}},
)

Allow-all is the useful default: it attaches the sidecar while leaving every destination reachable.

Why it is in this stack

It sits directly below #2403 because that PR's flagship example needs it. --provider-option hands the value to the provider; without this the provider rejects it and the example fails with Unknown OpenSandbox provider option(s): network_policy. Shipping the CLI flags without this would mean shipping a documented command that cannot run.

It is otherwise independent of the three layers below and could be reviewed on its own.

Two implementation notes

NetworkPolicy is imported inside _to_network_policy, not added to _require_opensandbox_sdk's return tuple. Widening that tuple touches all eight positional call sites plus every test fake — an earlier attempt produced five conflicts on a single upstream rebase. A local import costs nothing and keeps this independent of that helper's shape.

Conversion uses model_validate, not NetworkPolicy(**policy). The model field is default_action while the API spells it defaultAction; callers copy the API spelling, and validating by alias accepts both.

Validated

Used to drive a sandbox whose egress sidecar transparently redirects PyPI to an in-cluster cache. A bare pip install inside the container was served by nginx (cache=MISS first run, HIT on repeat) with nothing in the container configured to use it. That path is unreachable without this field.

Also verified through configuration alone — putting network_policy in a server's sandbox_spec.provider_options intercepts every sandbox that server creates, which is how an eval or RL run would use it, with no CLI involved.

Tests

Policy reaches the SDK and round-trips by alias; omitted when unset; non-mapping raises TypeError.

The provider had no way to send a networkPolicy, and provider_options rejects
unknown keys, so callers could not work around it.

That matters more than "one unsupported field" suggests. Server-side,
apply_egress_to_spec returns early when no policy is present, so the egress
sidecar is never attached at all -- meaning NO egress feature was reachable from
Gym: not filtering, not the credential proxy, not transparent MITM. Passing
{"defaultAction": "allow", "egress": []} attaches the sidecar while allowing all
traffic, which is what transparent registry interception needs.

NetworkPolicy is imported inside _to_network_policy rather than added to
_require_opensandbox_sdk's return tuple. Widening that tuple touches all eight
positional call sites and every test fake, and an earlier attempt at it produced
five conflicts on a single upstream rebase; a local import costs nothing and
keeps the change independent of that helper's shape.

Conversion uses model_validate rather than NetworkPolicy(**policy) because the
model field is default_action while the API spells it defaultAction; callers copy
the API spelling, and validating by alias accepts both.

Signed-off-by: Terry Kong <terryk@nvidia.com>
@copy-pr-bot

copy-pr-bot Bot commented Aug 7, 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.

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.

1 participant