fix(swift): keep device auth compatible with v2 gateways#80656
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 9, 2026, 4:31 AM ET / 08:31 UTC. Summary PR surface: Other +41. Total +41 across 5 files. Reproducibility: yes. with an older v2-only gateway: current main signs Swift connect with v3-only metadata, while the PR body shows live before/after logs where the old gateway rejected the signature before pairing and then reached Connected after the patch. Review metrics: 1 noteworthy metric.
Stored data model Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land the narrow connect-only compatibility helper now, then restore Swift connect to buildV3 or explicit signature-version negotiation once supported gateways verify v3 before v2. Do we have a high-confidence way to reproduce the issue? Yes, with an older v2-only gateway: current main signs Swift connect with v3-only metadata, while the PR body shows live before/after logs where the old gateway rejected the signature before pairing and then reached Connected after the patch. Is this the best way to solve the issue? Yes; this is the narrowest accepted mitigation because it limits v2 signing to Swift connect requests instead of weakening gateway verification or adding a broad auth fallback. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against c96163b6ca64. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Other +41. Total +41 across 5 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
Review history (1 earlier review cycle)
|
db0b8f8 to
a99c65a
Compare
|
This pull request has been automatically marked as stale due to inactivity. |
|
ClawSweeper PR egg 🔥 Warming up: real-behavior proof passed; findings, security review, or rank-up moves are still in progress. Hatch commandComment Hatchability rules:
What is this egg doing here?
|
|
Heads up: this PR needs to be updated against current |
a99c65a to
2e869b1
Compare
2e869b1 to
1df22ae
Compare
|
This assigned pull request has been automatically marked as stale after being open for 27 days. |
|
This assigned pull request has been automatically marked as stale after being open for 27 days. |
|
This assigned pull request has been automatically marked as stale after being open for 27 days. |
53ea982 to
3c4f6f0
Compare
|
Thanks for working to get this past the finish line!! @steipete 🦞 |
|
Maintainer fixup and landing proof
Best-fix judgment: yes for the explicitly approved temporary compatibility window. Permanent protocol negotiation would require additive challenge/schema/client/server work and is outside this bounded repair. |
|
Merged via squash.
|
) * fix(swift): keep device auth compatible with v2 gateways * refactor(swift): contain v2 auth compatibility * docs(changelog): note Swift v2 auth compatibility * chore(apple): sync native string inventory * chore: keep release changelog owned --------- Co-authored-by: Val Alexander <[email protected]> Co-authored-by: Peter Steinberger <[email protected]>
Summary
Why
Current gateway server code can verify both v3 and v2, but existing deployed gateways may still verify v2 only. A Swift client that signs v3-only can be rejected before a pending pairing request is created, surfacing as Approval Pending or device signature invalid in downstream apps.
Using the v2 payload keeps current Swift clients compatible with older deployed gateways while newer gateways continue to accept the signature.
Security and removal window
This temporary connect-only exception leaves the nonce, signed timestamp, token, role, scopes, device ID, and public key bound by the signature. The accepted tradeoff is that
platformanddeviceFamilyremain in the connect request but are not signature-bound by v2.Restore
buildV3, or add explicit signature-version negotiation, once managed and oldest-supported self-managed Gateways are expected to verify v3-before-v2. Do not reuse this helper outside the two Swift connect signers.Real behavior proof
Behavior or issue addressed: Swift OpenClawKit clients could sign gateway connect with the v3 device-auth payload while an already-deployed gateway verified only the v2 canonical payload. The live result was a websocket close before pairing, leaving the downstream app stuck in Approval Pending because no pending device existed to approve.
Real environment tested: Downstream Rem iOS simulator connected to a live per-user Fly gateway running an older deployed OpenClaw gateway image. Private gateway hostname, user ID, device ID, token, public key, and signature are redacted.
Exact steps or command run after this patch: Built and ran the downstream iOS app with this patched OpenClawKit commit, connected it to the live Fly gateway, opened Settings > Gateways, triggered explicit managed-cloud re-pair, watched app runtime logs, backend approval logs, and gateway websocket behavior, then visually confirmed the gateway status in the app.
Evidence after fix: Redacted runtime log excerpt from the patched downstream app/live Fly gateway validation:
Observed result after fix: The live gateway moved from device-signature-invalid before pairing to pairing required, backend auto-approve succeeded, the operator session connected, and the downstream app showed Settings > Gateways as Connected.
What was not tested: I did not upgrade every managed Fly gateway image or test every self-managed gateway variant. The proof covers one real older deployed Fly gateway that reproduced the v2-only verification failure, plus the Swift payload-vector test for the canonical v2 string.
Validation
3c4f6f0a59cbf0efbd986d6e4772557f9788bb3eincludes the Unreleased changelog entry; exact-head CI is the remaining landing gate.@clawsweeper re-review