Skip to content

Run cmux iOS over authenticated Iroh transport - #7908

Merged
azooz2003-bit merged 326 commits into
mainfrom
feat-iroh-runtime-0709
Jul 15, 2026
Merged

azooz2003-bit merged 326 commits into
mainfrom
feat-iroh-runtime-0709

Conversation

@azooz2003-bit

@azooz2003-bit azooz2003-bit commented Jul 11, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • run the macOS host and iOS client over authenticated Iroh by default
  • retain Tailscale and validated private-network routes as fallbacks
  • add same-account broker discovery, pair grants, managed relays, offline LAN policy, and multistream lanes
  • preserve active endpoints through transient broker failures and normalize legacy device UUID case without weakening device pinning

Verification

  • swift test --package-path Packages/Shared/CmuxIrohTransport --scratch-path /tmp/cmux-iroh-final-553f (249 tests, 33 suites)
  • tagged macOS irh2 build and isolated Simulator cmux-irh2-codex-151853
  • authenticated Iroh pair grant, one active Mac session, and iOS terminal round trip: IROH_IOS_ROUNDTRIP_1551
  • macOS 14 Intel compatibility run: https://github.com/manaflow-ai/cmux/actions/runs/29171266371
  • no physical device used

Stack


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.


Note

High Risk
Large new authenticated transport surface (admission, grants, broker credentials, multistream QUIC) plus auth/session-transition behavior; mistakes affect remote attach security and sign-in/sign-out races.

Overview
This PR makes authenticated Iroh the primary iOS↔Mac attach path, introduced via a new CmuxIrohTransport package (QUIC control stream, acknowledged NAT admission, broker grants/offline pairing, managed relays, multistream terminal/event/artifact lanes, and Mac-side admission quotas). CMUXMobileCore gains request-aware byte transports (CmxByteTransportRequest), a cloudRendezvous disclosure boundary (relay URLs only off-device), opaque hex network profile IDs, tighter path-hint rules (no IPv4 link-local / native private hints), CmxTailscaleStatusPeerResolver for storing numeric peers from local tailscale status, CmxCredentialedHTTPSession (no redirect credential leakage), and bounded MobileSyncFrameCodec / MobileHostRPCWorkQuota decoding.

CLI cmux remotes add docs now describe resolving *.ts.net against the authenticated local peer map and persisting the peer’s numeric address. Auth changes serialize browser sign-out (HostBrowserSignOutCoordinator), expose signOutRevision, and treat token reads during active sign-in/sign-out as retryable instead of clearing session state. CI adds CmuxIrohTransport Swift tests and an Intel macOS 14 compat matrix row with targeted package tests.

Reviewed by Cursor Bugbot for commit b310583. Bugbot is set up for automated code reviews on this repo. Configure here.


Summary by cubic

Default iOS↔Mac attach now runs over authenticated Iroh via CmuxIrohTransport, using a versioned multistream QUIC wire with an admission/NAT barrier and bounded peer streams. The iOS runtime owns endpoint/app‑instance identity, registers with signed challenges, rotates relay creds, caches verified offline policy, and defers activation until the signed‑in runtime is ready.

  • New Features

    • Iroh wire/host: versioned lane headers; acknowledged admission and NAT barrier; bounded incoming QUIC streams; independent server‑events; admitted multistream host sessions with per‑binding quotas.
    • Runtime: supervised endpoint generations; account‑scoped endpoint/app‑instance IDs; signed registration and discovery bound to the local app instance; managed‑relay rotation with online/offline admission leases; authenticated Bonjour LAN fallback; pooled client sessions that evict remotely closed connections.
    • Core/security: request‑aware transports via CmxByteTransportRequest; CmxIrohByteTransport adapts admitted control lanes and exposes CmxIndependentEventByteStream; MobileSyncFrameCodec adds a decoded‑frame count limit; MobileHostRPCWorkQuota bounds host work; CmxCredentialedHTTPSession blocks credentialed redirects; CmxTailscaleStatusPeerResolver persists numeric peers; relay hints require native public‑internet scope; IPv4 link‑local rejected.
    • Relay policy and CI/Auth: persisted broker relay credentials and an optional custom relay profile override; HostBrowserSignOutCoordinator serializes sign‑out and exposes signOutRevision; token reads during session transitions are retryable; CI runs CmuxIrohTransport tests and adds an Intel macOS 14 row.
  • Migration

    • cmux remotes add accepts numeric Tailscale IPv4/IPv6 or *.ts.net; MagicDNS resolves via the authenticated local peer map and stores the peer’s numeric address; plain LAN IPs, other hostnames, and loopback are rejected.
    • Cloud rendezvous, pairing QR, and paired‑Mac backups serialize relay URLs only.
    • CmxIrohNetworkProfileKey requires a canonical lowercase‑hex 32‑byte digest.

Written for commit b9bdb27. Summary will update on new commits.

Review in cubic

cmux reload-cloud added 3 commits July 14, 2026 12:39
…omerge

# Conflicts:
#	.github/swift-file-length-budget.tsv
#	cmux.xcodeproj/project.pbxproj
#	ios/Config/Shared.xcconfig
#	web/app/[locale]/(legal)/privacy-policy/page.tsx
#	web/app/env.ts
#	web/db/schema.ts
#	web/tests/client-config-env.test.ts
@azooz2003-bit
azooz2003-bit changed the base branch from feat-iroh-app-transport-0709 to main July 14, 2026 21:09
@cursor

cursor Bot commented Jul 14, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

…omerge

# Conflicts:
#	Packages/macOS/CmuxSidebarGit/Sources/CmuxSidebarGit/Model/WorkspaceGitSnapshotTaskContext.swift
#	Sources/BackgroundWorkspacePrimeCoordinator.swift
#	Sources/CmuxTopProcessEnumeration.swift
#	Sources/CmuxTopProcessSnapshotCache.swift
#	Sources/Mobile/MobileHostService.swift
#	Sources/Mobile/MobileTerminalByteTee.swift
#	cmux.xcodeproj/project.pbxproj
#	cmuxTests/MobileHostAuthorizationTests.swift
@cursor

cursor Bot commented Jul 14, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@azooz2003-bit
azooz2003-bit merged commit 3822f1d into main Jul 15, 2026
18 of 24 checks passed
austinywang pushed a commit that referenced this pull request Jul 15, 2026
Main's authenticated-Iroh transport work (#7908) made routeAllowsStackAuth
fail-closed (loopback only), which broke the Mac-to-Mac viewer: it dials
registry-advertised Tailscale routes and authorizes with the Stack token,
so every request threw insecureManualRoute ('Couldn't Connect').

Add an explicit StackAuthChannelTrust set on the policy and thread it
through MobileCoreRPCClient. iOS keeps the fail-closed default; only
HiveRemoteMacSession opts into loopbackAndTailscaleTunnel — the tunnel is
WireGuard-encrypted and the routes come from the signed-in account's own
device registry, and a non-tailnet host smuggled under the tailscale route
kind still never receives the token (policy test).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
austinywang added a commit that referenced this pull request Sep 1, 2026
Main's authenticated-Iroh transport work (#7908) made routeAllowsStackAuth
fail-closed (loopback only), which broke the Mac-to-Mac viewer: it dials
registry-advertised Tailscale routes and authorizes with the Stack token,
so every request threw insecureManualRoute ('Couldn't Connect').

Add an explicit StackAuthChannelTrust set on the policy and thread it
through MobileCoreRPCClient. iOS keeps the fail-closed default; only
HiveRemoteMacSession opts into loopbackAndTailscaleTunnel — the tunnel is
WireGuard-encrypted and the routes come from the signed-in account's own
device registry, and a non-tailnet host smuggled under the tailscale route
kind still never receives the token (policy test).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
teamleaderleo added a commit that referenced this pull request Sep 25, 2026
Pairing sends `workspace.list` and then an authenticated
`mobile.host.status` that binds the route to the Mac process before
anything is persisted (#7908, #8299). Twenty cmuxFeatureTests still
scripted only the workspace list. Their scripted transports spent the
list frame on the status request, or their routers answered it with
"Unexpected method", so every pairing ended in `connectionClosed` and
the assertions ran against the preview workspaces.

`remoteCreateTerminalDoesNotStealSelectionAfterWorkspaceSwitch` never
reached `terminal.create`, so its `waitForTerminalCreateRequest()`
parked forever and the full simulator suite hung until the job was
killed (exit 143, run 36114121829).

These tests were hidden while the iOS test target did not compile
(fixed in #14421). The passing neighbours, such as
`uuidAttachTicketListsAllWorkspacesFirstWithAttachToken`, already
script the status frame; this brings the rest in line. The version
warning test now checks that the warning sends nothing new instead of
pinning the total request count.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
teamleaderleo added a commit that referenced this pull request Sep 25, 2026
Pairing sends `workspace.list` and then an authenticated
`mobile.host.status` that binds the route to the Mac process before
anything is persisted (#7908, #8299). Twenty cmuxFeatureTests still
scripted only the workspace list. Their scripted transports spent the
list frame on the status request, or their routers answered it with
"Unexpected method", so every pairing ended in `connectionClosed` and
the assertions ran against the preview workspaces.

`remoteCreateTerminalDoesNotStealSelectionAfterWorkspaceSwitch` never
reached `terminal.create`, so its `waitForTerminalCreateRequest()`
parked forever and the full simulator suite hung until the job was
killed (exit 143, run 36114121829).

These tests were hidden while the iOS test target did not compile
(fixed in #14421). The passing neighbours, such as
`uuidAttachTicketListsAllWorkspacesFirstWithAttachToken`, already
script the status frame; this brings the rest in line. The version
warning test now checks that the warning sends nothing new instead of
pinning the total request count.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
teamleaderleo added a commit that referenced this pull request Sep 25, 2026
)

Pairing sends `workspace.list` and then an authenticated
`mobile.host.status` that binds the route to the Mac process before
anything is persisted (#7908, #8299). Twenty cmuxFeatureTests still
scripted only the workspace list. Their scripted transports spent the
list frame on the status request, or their routers answered it with
"Unexpected method", so every pairing ended in `connectionClosed` and
the assertions ran against the preview workspaces.

`remoteCreateTerminalDoesNotStealSelectionAfterWorkspaceSwitch` never
reached `terminal.create`, so its `waitForTerminalCreateRequest()`
parked forever and the full simulator suite hung until the job was
killed (exit 143, run 36114121829).

These tests were hidden while the iOS test target did not compile
(fixed in #14421). The passing neighbours, such as
`uuidAttachTicketListsAllWorkspacesFirstWithAttachToken`, already
script the status frame; this brings the rest in line. The version
warning test now checks that the warning sends nothing new instead of
pinning the total request count.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

This branch had an error being deployed

1 failed and 1 inactive (outdated) deployments
Preview – cmux — 8dfcc6ab Deployed Jul 15, 2026 by vercel[bot]
cloud-vm-staging — 92d6f088 Deployed Jul 13, 2026 by azooz2003-bit via migrate-staging #8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants