Skip to content

sandbox: --publish is inert under the default egress posture, and the CLI says otherwise #362

Description

@edgehero

Found while gating #337 item 1 (PR #361), pre-existing and out of that PR's scope.

What happens

PI_EGRESS unset means the policy is ARMED (worker/src/egress.mjs), so openSandbox puts the shell on its own --internal network. A container attached only to an internal network publishes nothing: docker accepts -p, exits 0, and binds no host port.

Measured on docker 27.4.0 (macOS):

$ docker network create --internal rbpub-net
$ docker run -d --name rbpub --network rbpub-net -p 127.0.0.1:18099:3000 busybox:latest sleep 60
$ docker ps --filter name=rbpub --format '{{.Ports}}'
                       # empty
$ docker port rbpub    # empty, exit 0

Meanwhile worker/src/sandbox-cli.mjs:105 prints published: 127.0.0.1:3000:3000, and docs/sandbox.md documents the flag with no caveat. So the one case --publish exists for, "start the app and click through it", silently does not work on a default deployment, and the tool reports that it does.

REQ-RESURRECTABLE-SANDBOX's Acceptance states it the same way: "Given --publish 3000, the port is reachable at 127.0.0.1". That is true only with PI_EGRESS=0.

Why it is not simply a bug in the flag

The two features are in genuine tension. The point of the internal network is that the sandbox reaches nothing the run could not; the point of --publish is to reach the sandbox from the host. They are opposite directions, so "fix the flag" is a design decision rather than a repair:

  • refuse --publish while egress is armed, naming PI_EGRESS=0 as the opt-out (honest, costs the feature on the default posture);
  • attach the bridge as a second network when --publish is given, which reopens the whole internet for that session and would have to say so loudly;
  • say it in the CLI line and the docs, and leave the behaviour (cheapest, and arguably enough given the flag is operator-typed).

Unmeasured

Docker Desktop on macOS only. Native Linux docker and Podman are unchecked, and the --internal semantics are the kind of thing that can differ.

Where the claims live

  • worker/src/sandbox-cli.mjs:105 (the published: line)
  • docs/sandbox.md, the --publish section
  • specs/requirements.md, REQ-RESURRECTABLE-SANDBOX Acceptance
  • specs/interfaces.md, INT-SANDBOX-CONTRACT Acceptance ("--publish 3000 yields 127.0.0.1:3000:3000", which is about the ARGV and stays true)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions