Repository navigation
Description
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 (
createGatewayOrigininpackages/core/src/devices/connect.ts), separate from LAN, loopback andtailscale servetraffic. 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 theHostheader. -
Refuse in one place. Mark the secret-bearing methods once, next to
markRemoteMethodsinpackages/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
privateInputSubmitandprivateInputReplace. 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. - unary
-
Refusal shape. Return a stable code such as
secret-route-refused, so the Web Client'sMethodRefusedand 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.
deepseekbotCLI commands run on the Host itself, so they need no change. Confirm thatpnpm lintCLI 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
DoodleBears commentedon Oct 21, 2026
Agent work claim
codex/local/01a15f6b-a5c1-7db2-b5b1-a33a1153fbc6(not a DSH Session)codex/2541-connect-secret-safetyDoodleBears commentedon Oct 21, 2026
Agent work continuation
codex/local/01a15fc3-2dc9-7e13-a9c5-8ca7f162d141(not a DSH Session)codex/local/01a15f6b-a5c1-7db2-b5b1-a33a1153fbc6at the Human's explicit continuation request; the prior chat ended interrupted following authentication failures.codex/2541-connect-secret-safetytest(connect): refresh audited routine capture fingerprint
DoodleBears commentedon Oct 21, 2026
Agent work outcome — handed off for review
codex/local/01a15fc3-2dc9-7e13-a9c5-8ca7f162d141. State: handed-off. This closes this task’s continuation claim and its superseded predecessor claim, not the issue.b842d3ce0750b5085106defef21c4d4eb0112f81; full CI passed. It retains the Human-confirmed full phone WebView removal and the central Connect secret-refusal boundary. It includes the still-open Remote Host chats render images and cards like local chats (#2500) #2533 dependency.DoodleBears commentedon Oct 22, 2026
Agent work resumed — authorized stack integration
codex/local/01a15fc3-2dc9-7e13-a9c5-8ca7f162d141; state active.b842d3ce0750b5085106defef21c4d4eb0112f81; feat(connect): encrypt paired-device traffic with pinned Noise XK #254744d2d17d99d0f896379272d582876e07eb3bd7da; current main8f4e650db. Remote Host chats render images and cards like local chats (#2500) #2533 was closed and its replacement feat(client): render remote messages through the source Host #2538 merged; preserve current source-Host routing and secret refusals together.merge: reconcile Connect refusal with current source-Host UI
merge: retain the current iOS composer qualification index
DoodleBears commentedon Oct 22, 2026
Agent work outcome — Track A merged
codex/local/01a15fc3-2dc9-7e13-a9c5-8ca7f162d141; state completed for Connect: refuse secret-bearing calls on the Connect route until it is end-to-end encrypted #2541.f267b7022951470cf8538d7d1ef12e1994b3fb5aafter exact-head full CI passed: https://github.com/BotHarness/DeepSeekBot/actions/runs/39732474568fix(connect): refuse secret entry and retire the mobile full client
merge: preserve remote cards and safety with current remote activity
test(connect): qualify secret refusal and mobile removal