Skip to content

platform: sandbox cell cannot reach tailnet serve endpoints (egress proxy empty-reply; no real tailscale interface) #1382

Closed

Description

@dezren39

PLATFORM BLOCKER (split from #1363, findings 2026-10-27): the laptop's opencode server is reachable over the tailnet via tailscale serve (HTTPS, verified end-to-end from real tailnet clients), but the Muse sandbox cell cannot use ANY tailscale-serve route:

  • The cell has no tailscale interface; its tailscale binary is a platform shim reporting "enrolled". Tailnet IPs route via the cell gateway (198.19.0.1); raw TCP to them returns "Operation not permitted".
  • DNS for *.raptor-pumpkinseed.ts.net resolves to a fake IP (198.18.161.121) owned by the egress stack.
  • The only egress is the Hatch egress proxy, which MITMs TLS (peer certs present as issued by "Hatch Sandbox Egress CA"). CONNECT + TLS to a serve endpoint complete, but every HTTP request to every serve port returns an empty reply (curl exit 52) — reproduced against the new opencode HTTPS serve, a temporary raw-TCP serve, and the pre-existing OpenChamber :3000 serve. SSH works only via the purpose-built CONNECT relay in ~/tools/laptop-proxy-connect.py.

What would unblock it (platform-level, any one of):

  1. Give the cell a real tailnet node/interface so serve endpoints are reachable directly; or
  2. Make the egress proxy pass CONNECT tunnels to tailnet serve ports through without the empty-reply behavior for client-first protocols (HTTP), as it already effectively does for SSH.

Until then the sandbox keeps the SSH-forward pattern (#1357 builds it as a helper) and #1363's from-the-sandbox end-state stays open. Evidence: #1363 result comment + the Tailscale-route addendum in the hub goal's opencode-access-benchmark-2026-10-27.md.

Acceptance criteria

  • A platform change lands (real tailnet interface in the cell, OR egress-proxy CONNECT pass-through for tailnet serve ports) and is evidenced by a successful HTTPS request from the sandbox cell to a *.raptor-pumpkinseed.ts.net serve endpoint (HTTP response, not an empty reply).
  • The reproduction from this issue (curl to the opencode serve endpoint and the OpenChamber :3000 serve) is re-run after the change and the result commented here.
  • Until then, this issue stays open as the platform-blocker record and feat(fleet): evaluate a tailnet-bound opencode serve option on the laptop for attach clients #1363's from-the-sandbox end-state references it.

Activity

  1. developing-today commented on Oct 27, 2026

    @developing-today
    Contributor
  2. added
    kind/infrastructureInfrastructure / host-portability work
    priority/highImportant and time-sensitive
    effort/lLarge: multi-day or open-ended; expect staged check-ins
    meta/enrichedIntake review done: acceptance criteria, links, and normalized labels added
    on Oct 27, 2026
  3. dezren39 commented on Oct 27, 2026

    @dezren39
    MemberAuthor

    Intake review

    Related: split from #1363 (tailnet-bound serve evaluation, enriched earlier today); #1357 (attach-first client helper) builds the SSH-forward workaround this blocker forces.

    Notes: reproduction is thorough — three different serve endpoints all return curl exit 52 (empty reply) through the egress proxy, while SSH via the purpose-built CONNECT relay works. This is a platform limitation, not a repo bug: no code in this repo can fix it.

    Risks: none to the repo; the risk is fleet work silently assuming serve routes work from the sandbox.

    Suggested approach: escalate to the platform side (Hatch egress/tailnet enrolment); keep the SSH-forward pattern as the documented route meanwhile. Priority high because it caps the #1363 end-state, effort l because the fix is platform-level.

    — fleet monitor intake enrichment, 2026-10-27.

  4. dezren39 commented on Oct 27, 2026

    @dezren39
    MemberAuthor

    Closing as INVALID — the premise was a testing error in the #1363 work: the sandbox reaches tailnet services through the documented tailnet proxy route (runtime proxy host, port 3130; ~/docs/devices/tailscale.md), which the blocked-tests never used (they went through the default 3128 egress proxy). Verified 2026-10-27: aggregator via 3130 → 200; the opencode tailscale-serve route via 3130 → 401 (auth enforced = reachable). No platform blocker exists for this path. See #1363's correction comment.

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

Metadata

Metadata

Assignees

Labels

effort/lLarge: multi-day or open-ended; expect staged check-inskind/infrastructureInfrastructure / host-portability workmeta/enrichedIntake review done: acceptance criteria, links, and normalized labels addedmeta/follow-upFollow-up spun out of earlier workpriority/highImportant and time-sensitivestatus:done

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions