Skip to content

Connect: refuse secret-bearing calls on the Connect route until it is end-to-end encrypted #2541

Closed

Description

@DoodleBears

Why

ADR-0241 Connect ends TLS at Cloudflare's edge, so Cloudflare can read device-gateway traffic in plaintext, secrets included. Vain decided on 2026-10-21 that this is not acceptable for user secrets. Until the Connect channel is end-to-end encrypted (see the sibling issue), a secret must never travel over the Connect route.

Connect has not shipped yet. Only testers use it, so this can change behaviour freely.

What

The Host refuses every secret-bearing bridge method when the request arrived through the Connect tunnel. The client then shows a clear notice instead of a form that fails silently.

  • Know the route on the Host. Connect traffic already arrives on its own loopback listener (createGatewayOrigin in packages/core/src/devices/connect.ts), separate from LAN, loopback and tailscale serve traffic. Tag requests there with the route kind, for both HTTP and WebSocket upgrades. Strip any client-supplied copy of that tag first, so it cannot be forged or removed from outside. Do not infer the route from the Host header.

  • Refuse in one place. Mark the secret-bearing methods once, next to markRemoteMethods in packages/core/src/bridge/rpc.ts, and refuse them at dispatch for Connect-tagged calls. Do not list paths in the gateway. Dispatch must cover all three entry points:

    • unary /botharness-device/api/botharness/<method>;
    • the full Web Client through /botharness-device/web/ (the phone's WebView, "安全填写");
    • any call carried on remote.mux.

    At minimum, mark privateInputSubmit and privateInputReplace. Also audit every other method that accepts a secret value: model provider API keys, IM bot tokens, private MCP server credentials and similar. Each one gets a test.

  • Refusal shape. Return a stable code such as secret-route-refused, so the Web Client's MethodRefused and the phone can map it to a notice.

  • Client notice. The private input card, and any settings form that takes a secret, shows the same notice on all three surfaces: the Web Client remote chat (Remote Host chats render images and cards like local chats (#2500) #2533), the phone, and the full client inside the WebView. The notice says, in English and Chinese, that secrets can only be entered on this computer or over Tailscale while Connect is not end-to-end encrypted. Status reads, cancel and revoke still work.

  • CLI parity. deepseekbot CLI commands run on the Host itself, so they need no change. Confirm that pnpm lint CLI parity still passes.

Acceptance

  • On a two-Host rig with Connect enabled (see the ADR-0241 tracer bullet), submitting a private input from the phone or from a remote browser over the Connect hostname is refused. The card shows the notice, and the Host logs only the phase name, never the value.
  • The same submission over loopback and over Tailscale still works.
  • A request that forges or strips the route tag over the Connect listener is still treated as Connect.
  • Unit tests cover the tagging, the dispatch refusal for each marked method, and the client notice.
  • Includes a bilingual changes/ fragment and light and dark screenshots of the notice.

Not in scope

End-to-end encryption itself (sibling issue). Removing this refusal is part of that issue's rollout.

Reported by Vain.

Activity

  1. DoodleBears commented on Oct 21, 2026

    @DoodleBears
    ContributorAuthor

    Agent work claim

    • Agent: Codex
    • Task: codex/local/01a15f6b-a5c1-7db2-b5b1-a33a1153fbc6 (not a DSH Session)
    • Issue scope: Trusted Connect route propagation, centralized secret-method refusal, secret input audit, and client notices; coordinate client changes with unmerged Remote Host chats render images and cards like local chats (#2500) #2533.
    • Branch: codex/2541-connect-secret-safety
    • Started: 2026-10-21 17:06 UTC
    • State: active
  2. added
    agent:activeOne or more coding-agent tasks currently claim this issue; see claim comments for task IDs
    on Oct 21, 2026
  3. self-assigned this
    on Oct 21, 2026
  4. DoodleBears commented on Oct 21, 2026

    @DoodleBears
    ContributorAuthor

    Agent work continuation

  5. DoodleBears commented on Oct 21, 2026

    @DoodleBears
    ContributorAuthor

    Agent work outcome — handed off for review

  6. removed
    agent:activeOne or more coding-agent tasks currently claim this issue; see claim comments for task IDs
    on Oct 21, 2026
  7. DoodleBears commented on Oct 22, 2026

    @DoodleBears
    ContributorAuthor

    Agent work resumed — authorized stack integration

  8. added
    agent:activeOne or more coding-agent tasks currently claim this issue; see claim comments for task IDs
    on Oct 22, 2026
  9. DoodleBears commented on Oct 22, 2026

    @DoodleBears
    ContributorAuthor

    Agent work outcome — Track A merged

  10. removed
    agent:activeOne or more coding-agent tasks currently claim this issue; see claim comments for task IDs
    on Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

ready-for-agentFully specified, ready for an AFK agent

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions