Repository navigation
feat(connect): encrypt paired-device traffic with pinned Noise XK - #2547
Conversation
|
Important Review skippedToo many files! This PR contains 115 files, which is 15 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry. ⚙️ Run configuration
⛔ Files ignored due to path filters: 31
📒 Files selected for processing: 115
You can disable this status message by setting the
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Issue: #2542 Agent-Task: codex/local/01a15fc3-2dc9-7e13-a9c5-8ca7f162d141
Native pairing fixed — head cb65e43Native diagnosis, screenshots, six-case receipt and cleanup.
PR remains Draft and stacked above #2546. No merge or release. The local HTML explainer is regenerated for this head; local-file browser policy still prevents a fresh visual inspection. The GitHub report and rendered native screenshots are reviewer-accessible. |
Issue: #2542 Agent-Task: codex/local/01a15fc3-2dc9-7e13-a9c5-8ca7f162d141
Issue: #2542 Agent-Task: codex/local/01a15fc3-2dc9-7e13-a9c5-8ca7f162d141
Reject untrusted enrollment and persisted carrier routes, including cached resources. Stop notification approvals after Connect failures and carry push settings through the encrypted gateway. Issue: #2542 Agent-Task: codex/local/01a15fc3-2dc9-7e13-a9c5-8ca7f162d141
Refs #2542 Agent-Task: codex/local/01a15fc3-2dc9-7e13-a9c5-8ca7f162d141 Claim: #2542 (comment)
Use the existing iOS modal presentation for the nested pairing stack so late content layout does not touch a dismissed form-sheet controller. Remove the first-use notice's iOS fade to avoid blocking touches when a pairing link opens immediately after it closes. Android stays unchanged. Reused QA iOS 27: six theme/text cases, same process before approval and after Settings/Activity use, plus the Maestro regression, Back/Close/swipe and QA chat. Includes red/green evidence and a bounded cleanup receipt. Refs #2542 Agent-Task: codex/local/01a15fc3-2dc9-7e13-a9c5-8ca7f162d141 Agent-Claim: #2542 (comment)
Show one pairing step at a time with complete selectable fingerprints, native actions and optional explanations. Settle cancelled confirmations without granting trust and preserve exact device-key approval. Issue: #2542 Agent-Task: codex/local/01a15fc3-2dc9-7e13-a9c5-8ca7f162d141
Issue: #2542 Agent-Task: codex/local/01a15fc3-2dc9-7e13-a9c5-8ca7f162d141
Route canonical message resources through encrypted reads and keep private-input capability gating. Scope delayed request/stream cleanup to each concrete owner; add receiving-endpoint tamper, replay, reconnect, substitution, concurrency, overload and lifecycle regressions. Issue: #2542 Agent-Task: codex/local/01a15fc3-2dc9-7e13-a9c5-8ca7f162d141
Issue: #2542 Agent-Task: codex/local/01a15fc3-2dc9-7e13-a9c5-8ca7f162d141
Keep strict route admission intact; the main-branch positive-path fixtures now use Tailscale HTTPS names rather than unsupported example domains. All 68 affected tests pass. Issue: #2542 Agent-Task: codex/local/01a15fc3-2dc9-7e13-a9c5-8ca7f162d141
Issue #2542 | Stack base #2546 | Agent claim
Requested by Vain; security choices approved by Vain. Implementation and verification: Codex.
Agent-Task:
codex/local/01a15fc3-2dc9-7e13-a9c5-8ca7f162d141Why the change
Connect needs an authenticated encrypted channel between the paired device and its Host so private input and normal app traffic can cross the tunnel without exposing their contents to the relay.
Special things to note
f267b7022951; this PR now targets main; the full phone WebView removal remains in Track A. New Connect pairings require independent Host fingerprint comparison and explicit approval of the device key. Existing unpinned Connect records refuse traffic and need re-pairing.f73bb4ecb7eb(all three full test shards, static/build, mobile verification, Android native modules, docs, Host smoke and aggregate gate); the documentation-only44d2d17d99d0follow-up also passed its full CI. Vain explicitly authorized merge on 2026-10-22 and deferred the integrated Simulator checks to the shared post-merge batch, with screenshots to be added to this PR afterward; deployment remains outside scope. Current integration full CI passed forc1b1eec18b7e; merged into main asebab8f9dcf78on 2026-10-22. The earlier integrated run found unsupported example-domain fixtures in three newly merged test files; those positive-path fixtures now use supported Tailscale HTTPS routes, with 68 affected tests passing and production route refusal unchanged.Change outline
Current main integration uses the canonical #2538 source-Host message/resource owner. Encrypted reads do not fall back to direct fetch; private input uses the owning client’s encryption capability. Delayed request/stream callbacks check their concrete instance before cleanup. Integration security report maps the additional #2542 criteria to receiving-endpoint tamper/replay/reconnect tests, concurrency, overload, revocation and lifecycle regressions. The replacement-stream regression fails without the guard and passes with it. This integration has types/lint/format and focused checks; historical screenshots keep their original source revisions.
Shared UI design standard (中文) now governs every new or changed Web, desktop and native interface. Repository instructions, mobile design, UI copy and the DSH UI skill reference one authority. Layout, icons and interaction carry the task; essential labels, accessibility and informed security decisions remain explicit. This follow-up changes documentation only; native evidence below retains its actual source revision.
Native fingerprint verification — existing QA iOS27, 402 × 874, English. The original alert becomes one focused step inside the pairing modal. Complete selectable fingerprints, native actions and optional explanation retain both trust checks. No native rebuild.
Before → after (light/default text):
Exact-source report and six-case receipt: light/dark × three text sizes passed full Host/device fingerprint comparison and immediate Settings/Activity/Chats use in the same process. Details, mismatch, Back and pending-approval Cancel passed; no pre-confirmation channel or fallback. Capture snapshot: 822 outer entries / 18 upgrades, fixed channel path, no credential headers, zero fallback. The existing Maestro same-process interaction flow also passed. Focused tests: 39 passed; mobile typecheck, lint, format and changelog checks passed. Android/physical devices/assistive technology and Chinese native rendering remain unverified; deployed account enrollment was not run at that historical source; the final Batch53 result below supersedes that gap. The password failure matrix below is prior evidence, separate from this presentation change. Temporary tunnel/DNS, task keys and own services were cleaned up; other pairings, Simulator and native build preserved.
Remote Web private input, before and after (synthetic account):
Mobile private-input form and cleared success state — Expo Web, not native QA:
Capture provenance and verification boundaries.
Real Cloudflare password verification — runtime source
683b0cbe, evidence-only commit606b1b75e7cb. Normal public DNS/TLS; 1,466 outer entries / 39 upgrades, no synthetic password or credential headers, zero fallback-trap requests.Trusted Web: before / rejected tunnel / explicit retry succeeded
Existing QA iOS27: masked real keyboard / failure / Handled with input removed
Verification method, native limitation and scope. Temporary tunnel/DNS, test device keys, synthetic credential and task services were cleaned up; existing devices and store app were preserved.
Native first pairing — existing QA iOS27, 402 × 874. Before: detent-controller error blocked interaction. After: new key approved, Chats/Settings/Activity usable in the same process. Android presentation is unchanged.
Native diagnosis, six-case receipt and cleanup. Includes Back, Close, downward swipe and opening the QA conversation. The first-use notice no longer fades on iOS, preventing overlap with immediate pairing; other sheets retain their default animation.
Main Simulator batch52 — real tunnel, partial acceptance
Actual main
55e0ce95200f, existing QA iOS27 + qualified installed client; no cold restart after first pairing. Full fingerprint/key approval, real DM, native masked password, HTTP502 refusal → explicit recovery/clearing, malformed-handshake refusal and revoked-device refusal passed. Outer pre-decryption capture: 3,240 records /82 channel upgrades, synthetic secret/application markers absent, fallback trap0; one deliberate plaintext QA probe404 was separate.At this baseline native image sending failed before upload (
Blob.arrayBufferunavailable). The later matched Batch53 recheck below verified repair #2578, now merged. This historical baseline is not deployed account-enrollment, physical/Android, complete accessibility or independent security acceptance.Exact-source report and limits.
First pairing: independently compare full Host fingerprint
Approve the exact phone key
Native password stays masked
Tunnel failure refuses submission
Explicit recovery succeeds and removes the input
Malformed handshake refuses submission
Revoked device refuses submission
Preserved original native image failure; follow-up #2578
Batch53 — native tracer completed with upload repair
Matched main
46bb44b2ff4freproduced native image failure; #2578ea36821ea929fixes it on the same existing QA iOS27/client. Actual native DM, PNG upload, private input and real tool approval passed, with owning Host evidence and zero plaintext fallback. HTTP502, malformed-handshake and revoked-device submissions remained pending/refused. Full CI39739723972 passed. Exact-source report and qualification limits. Formal account enrollment subsequently passed as recorded below; #2578 is merged and #2542 acceptance is complete.Formal account enrollment on deployed Connect also passed after the Human-authorized relay update (version
ebedbe4d-8b7c-42ce-bb68-5d8dcb630fa7). The full Host fingerprint matched an independent authenticated Host read; only the exact displayed phone key was approved. Native Settings immediately loaded over the managed Cloudflare tunnel and the Host reportedencrypted, with unchanged App PID4008. The former relay version rejected the current Host before trust; no plaintext pairing fallback was accepted. Account acceptance and coverage limits.Only the task phone key and temporary account Host/tunnel/DNS were removed after verification; original My Mac and devices were preserved. #2578 was merged as
4de4982443d501af9b68372848bc7fec36f7d7c4after explicit Human approval; #2542 acceptance is complete. Android, physical-device, CJK, VoiceOver and independent security qualification remain separately unrun.