Skip to content

fix(gateway): require node pairing before enabling node commands#57777

Merged
jacobtomlinson merged 3 commits intoopenclaw:mainfrom
jacobtomlinson:fix/fix-129
Mar 30, 2026
Merged

fix(gateway): require node pairing before enabling node commands#57777
jacobtomlinson merged 3 commits intoopenclaw:mainfrom
jacobtomlinson:fix/fix-129

Conversation

@jacobtomlinson
Copy link
Copy Markdown
Contributor

Summary

  • require an approved node pairing record before exposing any declared node commands at connect time
  • update gateway allowlist coverage to distinguish device-only pairing from full node pairing

Changes

  • changed the websocket connect path to intersect declared commands with the node pairing record even when no node pairing exists
  • added a regression for device-paired-only nodes and updated existing allowlist tests to perform explicit node pairing where command access is expected

Validation

  • Ran pnpm test -- src/gateway/server.roles-allowlist-update.test.ts -t "blocks all declared commands until node pairing exists"
  • Ran pnpm test -- src/gateway/server.roles-allowlist-update.test.ts
  • Ran pnpm check
  • Ran local agentic review with claude -p "/review" and addressed the follow-up test setup changes it implied

Notes

  • Residual risk or follow-up: older tests that assumed device pairing alone was sufficient for command access were updated to model explicit node pairing instead

@openclaw-barnacle openclaw-barnacle bot added gateway Gateway runtime size: S maintainer Maintainer-authored PR labels Mar 30, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 30, 2026

Greptile Summary

This PR closes a security gap in the gateway's node command access model: previously, a node that had completed device pairing but not full node pairing would still have its declared commands exposed at connect time. The fix collapses the two-branch pairedCommands logic (null meaning "no restriction" vs. a populated Set) into a single always-created Set, so an absent node pairing record yields an empty Set and silently filters every declared command. The test suite is updated with a dedicated connectNodeClientWithNodePairing helper that sequences the provisional connect → node-list lookup → stopAndWait → requestNodePairing/approveNodePairing → reconnect lifecycle, and a new regression test explicitly verifies the "device-paired-only" case returns zero commands and rejects invocations with the expected error message.

  • Core logic change in message-handler.ts is minimal, correct, and clearly expresses intent — no prior behaviour for the "node pairing present" path is altered.
  • The connectNodeClientWithNodePairing helper correctly stops the provisional client before issuing the node-pairing request so the nodeId is stable.
  • Existing tests that relied on device pairing alone for command access are properly migrated to the new helper.
  • The stopAndWaitconnectNodeClient flow (without re-wrapping in connectNodeClientWithPairing) is safe because device pairing was already persisted in the first call.

Confidence Score: 5/5

Safe to merge — the logic change is minimal and well-scoped, and the new regression test directly covers the fixed path.

All findings are P2 or below. The production change is a two-line simplification that removes a special-case null branch. The test helper uses the same connectNodeClient primitives already proven in the surrounding suite, and the regression test uses proper polling where needed. No data-loss, security, or correctness issues were identified.

No files require special attention.

Important Files Changed

Filename Overview
src/gateway/server/ws-connection/message-handler.ts Two-line change that collapses the 'no pairing → null → allow all' branch into an always-empty Set when pairedNode is absent, correctly enforcing that commands are blocked until a node pairing record exists.
src/gateway/server.roles-allowlist-update.test.ts Adds connectNodeClientWithNodePairing helper to perform full node pairing in test setup, updates two existing tests that expected command access to use it, and adds a regression test that verifies declared commands are blocked when only device pairing exists.

Reviews (1): Last reviewed commit: "Gateway: require node pairing for node c..." | Re-trigger Greptile

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: 34fe397048

ℹ️ 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".

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: 4e9ae24aca

ℹ️ 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".

@aisle-research-bot
Copy link
Copy Markdown

aisle-research-bot bot commented Mar 30, 2026

🤖 We're reviewing this PR with Aisle

We're running a security check on the changes in this PR now. This usually takes a few minutes. ⌛
We'll post the results here as soon as they're ready.

Progress:

  • Analysis
  • Finalization

Latest run failed. Keeping previous successful results. Trace ID: 019d3f7e91bbd79207099dfc043fd1f3.

Last updated on: 2026-03-30T16:43:55Z

Latest run failed. Keeping previous successful results. Trace ID: 019d3f91ef324cfbdd4734d7237becbb.

Last updated on: 2026-03-30T18:18:51Z

@jacobtomlinson jacobtomlinson merged commit 3886b65 into openclaw:main Mar 30, 2026
9 checks passed
@jacobtomlinson jacobtomlinson deleted the fix/fix-129 branch March 30, 2026 16:29
pgondhi987 pushed a commit to pgondhi987/openclaw that referenced this pull request Mar 31, 2026
…nclaw#57777)

* Gateway: require node pairing for node commands

* Gateway: request node pairing on initial connect

* Gateway: filter pending node pairing commands
pgondhi987 pushed a commit to pgondhi987/openclaw that referenced this pull request Mar 31, 2026
…nclaw#57777)

* Gateway: require node pairing for node commands

* Gateway: request node pairing on initial connect

* Gateway: filter pending node pairing commands
@steipete
Copy link
Copy Markdown
Contributor

steipete commented Apr 1, 2026

This broke things conceptually, reverting.

if I connect a node, node decides what it runs. not node AND gateway.

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: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants