Skip to content

Gateway: disconnect revoked device sessions#55952

Merged
jacobtomlinson merged 4 commits intoopenclaw:mainfrom
jacobtomlinson:fix/device-pair-remove
Mar 27, 2026
Merged

Gateway: disconnect revoked device sessions#55952
jacobtomlinson merged 4 commits intoopenclaw:mainfrom
jacobtomlinson:fix/device-pair-remove

Conversation

@jacobtomlinson
Copy link
Copy Markdown
Contributor

Summary

  • disconnect active gateway clients when a paired device is removed
  • disconnect active gateway clients when a device token is revoked

Changes

  • added a disconnectClientsForDevice hook to the gateway request context
  • wired the gateway runtime to close live sockets for a removed or revoked device
  • added handler-level regression tests covering both successful and failed disconnect paths

Validation

  • ran pnpm test -- src/gateway/server-methods/devices.test.ts
  • ran pnpm test -- src/gateway/server-methods/server-methods.test.ts -t "exec approval handlers"
  • ran pnpm check
  • ran pnpm build
  • ran local agentic review via claude -p "/review"; it requested a PR number or open-PR context, so there was no actionable feedback to apply locally

Notes

  • existing coverage for rejected fresh reconnects remains in the auth suite; this patch adds coverage for the live-session disconnect hook in the device handlers

@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime size: S maintainer Maintainer-authored PR labels Mar 27, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4886ec8e01

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/gateway/server-methods/devices.ts Outdated
Comment thread src/gateway/server-methods/devices.ts Outdated
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Mar 27, 2026

Greptile Summary

This PR adds live-session disconnect logic to the gateway device handlers: when a paired device is removed or a device token is revoked, all active WebSocket clients matching that deviceId are immediately closed (code 4001). The implementation wires a new disconnectClientsForDevice hook into GatewayRequestContext, provides the concrete implementation in server.impl.ts, and ships handler-level tests covering both success and failure branches.\n\nKey changes:\n- types.ts: new optional disconnectClientsForDevice?: (deviceId: string) => void on GatewayRequestContext\n- devices.ts: calls the hook (with optional chaining) after a confirmed successful removal or revocation\n- server.impl.ts: iterates the clients Set and closes matching sockets; errors are swallowed\n- devices.test.ts: four tests asserting that disconnect is called on success and not called on failure\n\nOne design concern to consider: device.token.revoke targets a single role's token, but the implementation disconnects every active session for the entire deviceId. If the same device can have multiple simultaneous connections under different roles (e.g., "admin" and "operator"), revoking the "operator" token will also force-close the valid "admin" session. device.pair.remove disconnecting all sessions is unambiguously correct; the revoke path may warrant role-scoped filtering (or at least a comment confirming the all-sessions intent is deliberate).

Confidence Score: 5/5

Safe to merge; the core logic is correct and well-tested, with only a P2 design question about role-scoped vs. device-scoped disconnection on token revoke.

All findings are P2 or lower. The implementation is straightforward, errors are properly guarded with optional chaining, the try/catch prevents iterator errors from propagating, and four new tests cover the critical happy-path and failure-path branches.

src/gateway/server.impl.ts — the disconnectClientsForDevice implementation uses device-level granularity for both remove and revoke; worth confirming role-scoped filtering is not needed for the revoke case.

Important Files Changed

Filename Overview
src/gateway/server-methods/devices.ts Added context.disconnectClientsForDevice?.(deviceId) after successful device.pair.remove and device.token.revoke operations. Both paths correctly guard on a truthy result before calling the hook.
src/gateway/server-methods/types.ts Added optional disconnectClientsForDevice?: (deviceId: string) => void field to GatewayRequestContext, consistent with the existing optional hasExecApprovalClients.
src/gateway/server.impl.ts Implements disconnectClientsForDevice by iterating the clients Set and closing matching sockets. The same close code (4001) and reason ('device removed') is used for both removal and revocation.
src/gateway/server-methods/devices.test.ts New test file covering all four relevant paths: successful and failed remove/revoke. Mocks are correctly hoisted and all key assertions are present.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/gateway/server.impl.ts
Line: 1199-1210

Comment:
**Token revoke disconnects all device sessions regardless of role**

`device.token.revoke` revokes a token for a *specific* role (e.g., "operator"), but `disconnectClientsForDevice` closes every active socket for the entire `deviceId`. If a device has simultaneous connections for different roles (e.g., one session as "operator" and another as "admin"), revoking the "operator" token will also drop the still-valid "admin" session.

`device.pair.remove` disconnecting all sessions for the device is correct — the whole device is de-paired. But for `device.token.revoke`, the intent is presumably to invalidate a single role's token. The implementation in `devices.ts` calls the same broad helper for both operations, so there is no per-role filtering.

If the correct behaviour really is "revoke any one token → disconnect every session for the device", that should be documented. If not, consider adding a `role?: string` parameter to `disconnectClientsForDevice` so the iterator can additionally check `gatewayClient.connect.role === role` before closing.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "Gateway: disconnect revoked device sessi..." | Re-trigger Greptile

Comment thread src/gateway/server.impl.ts Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d13c5bdde9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/gateway/server-methods/devices.ts Outdated
@jacobtomlinson jacobtomlinson merged commit 7a801cc into openclaw:main Mar 27, 2026
28 of 45 checks passed
@jacobtomlinson jacobtomlinson deleted the fix/device-pair-remove branch March 27, 2026 19:01
johnkhagler pushed a commit to johnkhagler/openclaw that referenced this pull request Mar 29, 2026
* Gateway: disconnect revoked device sessions

* Gateway: normalize device disconnect targets

* Gateway: scope token revoke disconnects by role

* Gateway: respond before disconnecting sessions
alexcode-cc pushed a commit to alexcode-cc/clawdbot that referenced this pull request Mar 30, 2026
* Gateway: disconnect revoked device sessions

* Gateway: normalize device disconnect targets

* Gateway: scope token revoke disconnects by role

* Gateway: respond before disconnecting sessions
lovewanwan pushed a commit to lovewanwan/openclaw that referenced this pull request Apr 28, 2026
* Gateway: disconnect revoked device sessions

* Gateway: normalize device disconnect targets

* Gateway: scope token revoke disconnects by role

* Gateway: respond before disconnecting sessions
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
* Gateway: disconnect revoked device sessions

* Gateway: normalize device disconnect targets

* Gateway: scope token revoke disconnects by role

* Gateway: respond before disconnecting sessions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gateway Gateway runtime maintainer Maintainer-authored PR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant