Skip to content

fix(swift): keep device auth compatible with v2 gateways#80656

Merged
steipete merged 5 commits into
openclaw:mainfrom
samuelalake:codex/remclaw-device-auth-v2-compat
Jul 9, 2026
Merged

fix(swift): keep device auth compatible with v2 gateways#80656
steipete merged 5 commits into
openclaw:mainfrom
samuelalake:codex/remclaw-device-auth-v2-compat

Conversation

@samuelalake

@samuelalake samuelalake commented May 11, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add one connect-only Swift compatibility payload builder while retaining the existing v3 builder.
  • Sign shared Swift and macOS wizard connect requests with the v2 canonical payload for deployed gateways that have not yet upgraded to v3 verification.
  • Add a regression vector for the compatibility payload and keep the exception's restoration trigger at the builder.

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 platform and deviceFamily remain 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:

before patch:
gateway websocket closed before connect: code=1008 reason=device signature invalid
gateway paired devices: existing cli/operator record only
gateway pending devices: []
backend approve-device: auto-approve timed out: no pending devices found

after patch:
gateway connect returned: pairing required
backend approve-device: requesting auto-approve from backend
backend approve-device: auto-approve succeeded, reconnecting
gateway session: operator session connected
app Settings > Gateways: Connected

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

  • SwiftPM DeviceAuthPayloadTests passed.
  • Downstream iOS build and simulator run passed.
  • Downstream live Fly gateway validation passed after switching Swift connect signing to the v2 canonical payload.
  • Fresh maintainer SwiftFormat lint and autoreview passed after removing the redundant public v2 alias/test.
  • Rebased head 3c4f6f0a59cbf0efbd986d6e4772557f9788bb3e includes the Unreleased changelog entry; exact-head CI is the remaining landing gate.

@clawsweeper re-review

@openclaw-barnacle openclaw-barnacle Bot added size: S triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 11, 2026
@clawsweeper

clawsweeper Bot commented May 11, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 9, 2026, 4:31 AM ET / 08:31 UTC.

Summary
The PR adds a Swift connect-only v2 compatibility payload builder, switches the shared OpenClawKit and macOS wizard connect signers to it, and adds a Swift payload vector test while leaving the v3 builder intact.

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.

  • Swift connect auth surface: 2 signers changed, 1 compatibility builder added. These are the compatibility and security-sensitive paths reviewers need to focus on before merge.

Stored data model
Persistent data-model change detected: vector/embedding metadata: apps/shared/OpenClawKit/Tests/OpenClawKitTests/DeviceAuthPayloadTests.swift. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Overall: 🦞 diamond lobster
Proof: 🦞 diamond lobster
Patch quality: 🦞 diamond lobster
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Risk before merge

  • [P1] The PR intentionally leaves platform and deviceFamily out of Swift connect signatures until supported gateways verify v3-before-v2; the public maintainer note accepts that temporary security-boundary tradeoff.
  • [P1] The live proof covers one older deployed Fly gateway plus payload-vector tests, not every self-managed gateway variant.

Maintainer options:

  1. Land the accepted compatibility window (recommended)
    Merge the narrowed v2 Swift connect-signing helper and keep the restoration trigger tied to gateway fleet support for v3-first verification.
  2. Require negotiation before merge
    Pause this PR and implement explicit signature-version negotiation if maintainers no longer want platform and deviceFamily outside the signature during the transition.

Next step before merge

  • No automated repair is needed; the remaining action is normal maintainer landing with exact-head gates for an already narrowed and proof-backed patch.

Security
Cleared: No supply-chain change was found; the auth-boundary change is deliberate, documented, and maintainer-accepted as a temporary Swift connect compatibility window.

Review details

Best 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 changes

Label changes:

  • add merge-risk: 🚨 compatibility: Merging changes Swift connect signing behavior to preserve compatibility with older deployed gateways while newer gateways still accept v2.
  • add merge-risk: 🚨 security-boundary: The temporary v2 payload no longer binds platform and deviceFamily into the Swift connect signature, even though nonce, timestamp, token, role, scopes, device id, and public key remain signed.
  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body supplies redacted live gateway logs and app status after the fix, and a maintainer comment adds focused gateway and Swift payload test proof for the code-changing head.
  • add rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦞 diamond lobster and patch quality is 🦞 diamond lobster.

Label justifications:

  • P1: Swift clients can be rejected before pairing on deployed v2-only gateways, leaving downstream apps stuck in Approval Pending or device-signature-invalid.
  • merge-risk: 🚨 compatibility: Merging changes Swift connect signing behavior to preserve compatibility with older deployed gateways while newer gateways still accept v2.
  • merge-risk: 🚨 security-boundary: The temporary v2 payload no longer binds platform and deviceFamily into the Swift connect signature, even though nonce, timestamp, token, role, scopes, device id, and public key remain signed.
  • rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦞 diamond lobster and patch quality is 🦞 diamond lobster.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body supplies redacted live gateway logs and app status after the fix, and a maintainer comment adds focused gateway and Swift payload test proof for the code-changing head.
Evidence reviewed

PR surface:

Other +41. Total +41 across 5 files.

View PR surface stats
Area Files Added Removed Net
Source 0 0 0 0
Tests 0 0 0 0
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 5 56 15 +41
Total 5 56 15 +41

What I checked:

Likely related people:

  • BunsDev: Assigned to the PR, authored the main compatibility commit, and posted the maintainer note accepting the temporary v2 Swift connect signing window with proof expectations. (role: compatibility decision owner; confidence: high; commits: 9f1de96e6780; files: apps/shared/OpenClawKit/Sources/OpenClawKit/DeviceAuthPayload.swift, apps/shared/OpenClawKit/Sources/OpenClawKit/GatewayChannel.swift, apps/macos/Sources/OpenClawMacCLI/WizardCommand.swift)
  • steipete: Force-pushed the current head, contained the v2 helper to a single connect-only API, synced the native inventory, and removed release-owned changelog content. (role: recent branch maintainer; confidence: high; commits: 2b00c769954d, 3c4f6f0a59cb, 8d3c6183a31b; files: apps/shared/OpenClawKit/Sources/OpenClawKit/DeviceAuthPayload.swift, apps/shared/OpenClawKit/Tests/OpenClawKitTests/DeviceAuthPayloadTests.swift, apps/.i18n/native-source.json)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (1 earlier review cycle)
  • reviewed 2026-07-04T03:47:47.901Z sha 93d5fa5 :: needs maintainer review before merge. :: none

@openclaw-barnacle openclaw-barnacle Bot added proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 11, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 11, 2026
@samuelalake
samuelalake force-pushed the codex/remclaw-device-auth-v2-compat branch from db0b8f8 to a99c65a Compare May 11, 2026 13:15
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 11, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 11, 2026
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label May 26, 2026
@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. labels May 26, 2026
@clawsweeper

clawsweeper Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg

🔥 Warming up: real-behavior proof passed; findings, security review, or rank-up moves are still in progress.

Hatch command

Comment @clawsweeper hatch when this PR is hatchable.

Hatchability rules:

  • Merged PRs are hatchable.
  • Open PRs are hatchable when they are status: 👀 ready for maintainer look, status: 🚀 automerge armed, or labeled clawsweeper:automerge.
  • Closed unmerged PRs are hatchable only when one of those hatchable labels is still present in the durable record.
What is this egg doing here?
  • Eggs appear after the PR passes real-behavior proof. It is here for vibes, not verdicts: it does not change labels, ratings, merge decisions, or automation.
  • The shell reacts to review momentum: open follow-up work warms it up, re-review makes it wobble, and a clean final review lets it hatch.
  • Hatchability usually comes from sufficient real-behavior proof, no blocking P0/P1/P2 findings, no security attention needed, and clean correctness. A merged PR is already final, so merge makes the egg hatchable independently.
  • The hatch is seeded from this repository and PR number, so the same PR keeps the same creature; the reviewed head SHA can only change safe visual details.
  • Rarity is just collectible sparkle: 🥚 common, 🌱 uncommon, 💎 rare, ✨ glimmer, and 🌈 legendary.

@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label May 27, 2026
@clawsweeper clawsweeper Bot added status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels May 27, 2026
@RomneyDa

Copy link
Copy Markdown
Member

Heads up: this PR needs to be updated against current main before the new required Dependency Guard check can pass.

@samuelalake
samuelalake force-pushed the codex/remclaw-device-auth-v2-compat branch from a99c65a to 2e869b1 Compare May 30, 2026 17:16
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 30, 2026
@samuelalake

Copy link
Copy Markdown
Contributor Author

@RomneyDa thanks for the heads up. I rebased this PR onto current main and pushed the updated branch. Dependency Guard has started running again on head 2e869b1. Local check: swift test --filter DeviceAuthPayload passes in apps/shared/OpenClawKit.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. labels May 30, 2026
@samuelalake
samuelalake force-pushed the codex/remclaw-device-auth-v2-compat branch from 2e869b1 to 1df22ae Compare May 30, 2026 19:30
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 30, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 30, 2026
@clawsweeper clawsweeper Bot added the status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. label Jun 15, 2026
@openclaw-barnacle

Copy link
Copy Markdown

This assigned pull request has been automatically marked as stale after being open for 27 days.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Jun 16, 2026
@clawsweeper clawsweeper Bot added status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jun 24, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Jun 24, 2026
@openclaw-barnacle

Copy link
Copy Markdown

This assigned pull request has been automatically marked as stale after being open for 27 days.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Jun 24, 2026
@clawsweeper clawsweeper Bot added status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jun 24, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Jun 25, 2026
@openclaw-barnacle

Copy link
Copy Markdown

This assigned pull request has been automatically marked as stale after being open for 27 days.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Jun 25, 2026
@steipete
steipete force-pushed the codex/remclaw-device-auth-v2-compat branch from 53ea982 to 3c4f6f0 Compare July 9, 2026 07:54
@samuelalake

samuelalake commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for working to get this past the finish line!! @steipete 🦞

@clawsweeper clawsweeper Bot removed proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jul 9, 2026
@steipete

steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Maintainer fixup and landing proof

  • Exact head: a5a89fe06f212b83362d834a08899167f9d1f5cd.
  • Contained the compatibility exception to one Swift connect-only builder used by the shared Gateway client and macOS wizard; the general buildV3 API remains unchanged.
  • Current TypeScript servers verify v3 first and then v2. Older deployed Gateways advertise only nonce/timestamp, so they cannot negotiate a v3 client signature before this compatibility path is used.
  • Accepted temporary tradeoff: platform and deviceFamily remain transmitted but are not signature-bound on these two Swift connect paths. Nonce/challenge, device ID/public key, timestamp, role, scopes, and auth token remain bound.
  • Removal trigger: restore Swift v3-only signing, or add explicit negotiation, when managed and oldest supported self-managed Gateways all verify v3-before-v2.
  • Live downstream iOS/Fly proof: v3 was rejected before pairing; the canonical v2 payload reached pairing, auto-approval, and Connected.
  • Exact-SHA release-gate CI run 29006641750: all required checks passed, including macos-swift, ios-build, Gateway/server tests, native-i18n, lint, and security-fast.
  • Focused proof: Swift DeviceAuthPayload 4 tests passed; Gateway device-auth 24 tests passed; SwiftFormat lint passed; fresh autoreview clean.
  • scripts/pr review-validate-artifacts 80656: passed.

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.

@steipete
steipete merged commit 3f2466c into openclaw:main Jul 9, 2026
246 of 254 checks passed
@steipete

steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 10, 2026
)

* 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]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: macos App: macos P1 High-priority user-facing bug, regression, or broken workflow. proof: supplied External PR includes structured after-fix real behavior proof. size: S stale Marked as stale due to inactivity

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants