Repository navigation
fix(ios): accept the Mac's push key exchange (device id) and allow Simulator push verification - #14292
Conversation
…nge rejections A Release build running in the Simulator registered its device token as production, but the Simulator only mints sandbox tokens, so APNs rejected every push and the official app could never be push-verified there. The push key exchange also failed silently: a rejected reply or missing context logged only "attempt failed". It now names the mismatched or missing field (never its value) so a device log shows why the Mac's key was not pinned. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The phone compared the key-exchange reply's mac_device_id with the host
status mac_device_id. The status carries the team-directory computer
identity, the reply carries the physical device identity that push
tuples use, so every exchange was rejected ("key exchange reply
rejected: mac_device" in a Simulator run of the Release com.cmux.app)
and the Mac's key was never pinned.
Reply validation moves onto MobilePhonePushKeyExchangeResponse
(mismatchedFields) and compares only account, instance tag, and build
namespace; the pin keeps the reply's physical device id, which matches
the tuple the Mac encrypts with.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
All contributors have signed the CLA ✍️ ✅ |
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: manaflow-ai/cmux/.coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (4)
Included review availability: Your plan provides up to 10 included reviews per hour; 7 remain after this review. 📝 WalkthroughWalkthroughPhone push key exchange no longer requires a Mac device ID and now reports mismatched reply fields. APNs environment selection now uses sandbox for Simulator builds as well as DEBUG builds. ChangesPhone push key exchange
APNs environment selection
Priority: ➖ Normal Estimated code review effort: 2 (Simple) | ~10 minutes Change: Bug fix Merge Risk: ⚪ Minimal · up to No actionable merge-blocking risk is established for the push key exchange or Simulator APNs changes. Normal validation can proceed before merging. 🚥 Pre-merge checks | ✅ 23 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (23 passed)
Full details: Description checkExplanation The description provides a detailed Summary and Testing section, including added tests and an end-to-end Simulator result. However, it omits the required Demo Video or screenshots and the repository Checklist, including deterministic soak coverage, documentation status, and bot-review confirmation. Resolution Add the required Demo Video or screenshots for this behavior change. Include the Checklist and address each applicable item, especially deterministic soak coverage, docs or changelog updates, localization if applicable, and bot-review status.
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
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 |
cbe0bd9 ci: seed the macOS 15 pool with its own Xcode (manaflow-ai#14315) 5fab6f5 refactor: move CmuxWebView into CmuxBrowser behind an injected host (manaflow-ai#14321) 8475872 Merge pull request manaflow-ai#14335 from manaflow-ai/13458-safe-device-rollout 2f7bd16 fix(ios): accept the Mac's push key exchange (device id) and allow Simulator push verification (manaflow-ai#14292) fd66cc7 ci: give an owned Mac's second compile slot its own canonical root (manaflow-ai#14338) af4097b ci: build cmuxTests without the compilation cache so it rebuilds incrementally (manaflow-ai#14349) fe61107 ci: replay input times onto an owned Mac's kept DerivedData (manaflow-ai#14346) f7b8848 Freeze the historical socket migration in the rollback fixture 73c3a07 fix(web): store sandbox for production-bundle installs that declare it (manaflow-ai#14296) c04616b Merge remote-tracking branch 'origin/main' into 13458-safe-device-rollout 459d89c ci: read the owned pools' free machines live through the org route App (manaflow-ai#14350) 2b7afe3 ci: give the iOS upload workflows the R2 cache URL (manaflow-ai#14347) 359f14c test: tie the E2E stale-snapshot case to OWNED_MAX_AGE_MINUTES (manaflow-ai#14348) 1fcef82 Update CI guard expectations and require the passing layout regression 9b5a251 Merge remote-tracking branch 'origin/main' into 13458-safe-device-rollout 60ab69a Exercise remote mirror pane replacement in the workspace regression 7a0ba5d Merge remote-tracking branch 'origin/main' into 13458-safe-device-rollout 1649314 Preserve remote Mac workspaces across sidebar creation and pane replacement 52fec11 Observe asynchronous remote cleanup in the creation regression a93af4d Reproduce remote workspace deletion when its local placeholder is replaced bc0a0ad Test sidebar workspace creation preserves the remote Mac target 93aff4d ci: quote development Worker revision arguments 24475c2 Merge remote-tracking branch 'origin/main' into 13458-safe-device-rollout 57331a9 fix: make Devices rollout preserve SQLite rollback compatibility 448eeb2 test: reproduce unsafe Devices rollout assumptions # Conflicts: # .github/workflows/ci-guards.yml # .github/workflows/ci-macos.yml # .github/workflows/ci.yml # .github/workflows/ios-appstore-upload.yml # .github/workflows/ios-testflight.yml # .github/workflows/iroh-v2-production-drift.yml # .github/workflows/iroh-v2.yml # .github/workflows/seed-derived-data.yml
Summary
Encrypted pushes still showed "cmux / An agent needs your attention" after #14039, #14110, and #14267. A Release
com.cmux.apprunning on an isolated Simulator, paired with a nightly Mac, logged the real cause:The phone compared the key-exchange reply's
mac_device_idwith the host statusmac_device_id, but they identify different things. The status carries the team-directory computer identity (authorizedDeviceID ?? v2DeviceIDinMobileHostTransportAuthorization), while the reply carriesMobileHostIdentity.deviceID(), the physical identity that push tuples use. Every exchange was rejected, so the phone never pinned the Mac's key, and the notification extension failed each push withsender_not_pinned.Changes:
MobilePhonePushKeyExchangeResponse.mismatchedFields, which compares account, instance tag, and build namespace. The pin still uses the reply's physical device ID, which matches the tuple the Mac encrypts with.sandbox. The Simulator only issues sandbox tokens, so without this APNs rejected every push and the official app could not be push-verified there.Testing
CMUXMobileCore: newMobilePhonePushKeyExchangeResponseTestscover a reply whose device ID differs from the status, which is accepted, and contradicting account, tag, or namespace fields, which are named.CmuxMobileShellbuilds forarm64-apple-ios17.0-simulator.com.cmux.app: CI builds with the App Store lane's settings, ad-hoc signed so the release entitlements are simulated. The app signs in with the personal account, pairs with a nightly Mac, then receives a push. Before this change the run logged themac_devicerejection above. With this change, the same Simulator session connected with no key-exchange rejection, and the nightly Mac pinned the Simulator's installationb926b6cf. After fix(web): store sandbox for production-bundle installs that declare it #14296 deployed, the install re-registered assandbox. A realcmux notifyfrom the nightly Mac returned APNs 200 for that install. The Simulator's notification extension decrypted the push without logging a failure reason, and the lock-screen banner read "Push test 19:42:06: If you can read this line, the phone decrypted the push."🤖 Generated with Claude Code