Skip to content

fix(gateway): authorize plugin methods from attached registry#94343

Merged
steipete merged 5 commits into
openclaw:mainfrom
wangmiao0668000666:fix/workboard-scope-classification-92044-clean
Jun 19, 2026
Merged

fix(gateway): authorize plugin methods from attached registry#94343
steipete merged 5 commits into
openclaw:mainfrom
wangmiao0668000666:fix/workboard-scope-classification-92044-clean

Conversation

@wangmiao0668000666

Copy link
Copy Markdown
Contributor

Summary

openclaw workboard dispatch CLI was failing with missing scope: operator.admin even though workboard.cards.dispatch is registered with scope: operator.write. The root cause: resolveScopedMethod only consulted activeRegistry.gatewayMethodDescriptors, but plugin descriptors can also live in the httpRoute or channel surface, so a request entering through those surfaces silently fell through to the admin default in authorizeOperatorScopesForMethod. The fix looks across all three active surfaces, with the active surface still winning when it has the descriptor. The admin fallback for genuinely unknown methods is preserved.

This is the same root-cause shape as #78894 (memory-core dream-promotion cron) and a latent risk for every other plugin that uses api.registerGatewayMethod (workboard, memory-wiki, voice-call, google-meet, matrix, browser). Fixing it once in the resolver covers all of them.

Supersedes #94047 (which accumulated noise commits during CI re-runs and real-time fix discovery).

Problem

  • workboard.cards.dispatch is registered with { scope: operator.write } and is not in a reserved-admin namespace.
  • resolveScopedMethod looked the method up in getPluginRegistryState()?.activeRegistry?.gatewayMethodDescriptors and found no descriptor for it, so it returned undefined.
  • authorizeOperatorScopesForMethod then did resolveRequiredOperatorScopeForMethod(method) ?? ADMIN_SCOPE and rejected the CLI's ["operator.write", "operator.read"] with missing scope: operator.admin.
  • The dashboard "Run" only worked because paired operator devices carry operator.admin, which short-circuits the check.
  • Generic caller openclaw gateway call workboard.cards.dispatch --params '{}' masked the bug because it requests the full default operator scope set (which includes admin) for unclassified methods.

Solution

resolveScopedMethod now consults all three active surfaces in priority order — activehttpRoutechannel — when looking up a plugin descriptor. The active surface still wins when it has the descriptor. The admin fallback for unknown methods is preserved (covered by a regression test).

Changes

  • src/gateway/method-scopes.ts:43-71 — extract findPluginMethodDescriptor helper that walks all three active surfaces; resolveScopedMethod now uses it.
  • src/gateway/method-scopes.test.ts:208-381 — 6 new tests:
  • scripts/repro/issue-92044-workboard-scope.mjs — standalone live proof with 5 cases against real production code (no vitest mocks).
  • scripts/repro/issue-92044-workboard-e2e.mjs — production-surface proof showing descriptor counts after setActivePluginRegistry and the resulting scope resolution.
  • test/scripts/lint-suppressions.test.ts — register the new use-unknown-in-catch-callback-variable suppression from the repro script in the explicit allowlist.

Real behavior proof

  • Behavior addressed: plugin-declared scopes reach the scope resolver regardless of which active surface (active / http-route / channel) holds the descriptor; unknown methods still fall through to the admin default.

  • Real environment tested: Linux x86_64, Node 22.22.0, OpenClaw source checkout, branch fix/workboard-scope-classification-92044-clean. Reproduced against compiled prod build (pnpm build exit 0).

  • Exact steps or command run after this patch:

    • node --import tsx scripts/repro/issue-92044-workboard-scope.mjs — PASS, 5/5 cases
    • node --import tsx scripts/repro/issue-92044-workboard-e2e.mjs — PASS
    • node scripts/run-vitest.mjs src/gateway/method-scopes.test.ts --run — 324/324 pass
    • node scripts/run-vitest.mjs src/gateway/methods/registry.test.ts --run — 20/20 pass
    • node scripts/run-vitest.mjs src/gateway/server-plugins.test.ts --run — 98/98 pass
    • node scripts/run-vitest.mjs src/plugins/runtime.test.ts --run — 16/16 pass
    • node scripts/run-vitest.mjs extensions/workboard/src/gateway.test.ts --run — 4/4 pass
    • node scripts/run-vitest.mjs test/scripts/lint-suppressions.test.ts --run — 3/3 pass
    • node scripts/run-oxlint.mjs <touched files> — clean
    • pnpm tsgo — exit 0
    • pnpm build — exit 0
  • Evidence after fix: terminal output of the standalone repro script on Linux x86_64 / Node 22.22.0, captured locally and pasted below.

    === Reproduction for issue #92044 ===
    
    --- Case 1: workboard.cards.dispatch on http-route surface ---
    resolveRequiredOperatorScopeForMethod = operator.write
    authorize([operator.write]) = { allowed: true }
    authorize([operator.read]) = { allowed: false, missingScope: 'operator.write' }
    
    --- Case 2: workboard.cards.dispatch on channel surface ---
    resolveRequiredOperatorScopeForMethod = operator.write
    
    --- Case 3: active surface takes priority over http-route ---
    resolveRequiredOperatorScopeForMethod = operator.write
    
    --- Case 4: unknown method falls through to admin default ---
    authorize(totally.unknown.method, [operator.write]) = { allowed: false, missingScope: 'operator.admin' }
    
    --- Case 5: memory-core style descriptor on channel surface ---
    resolveRequiredOperatorScopeForMethod = operator.write
    
    PASS: plugin-declared scopes are resolved across all active surfaces.
    
  • Observed result after fix: all five cases produce the expected scope and authorization result. The unknown-method admin default is preserved. The same code path the CLI hits is exercised end-to-end with real production code (no vitest mocks).

  • What was not tested: an end-to-end run of openclaw workboard dispatch against a live gateway with token-auth CLI. The repro covers the same code path the CLI hits, but I did not exercise the bundled binary on a real install.

Revert test (proof the fix is necessary, not redundant)

I temporarily reverted src/gateway/method-scopes.ts:43-58 to the pre-fix single-surface lookup and re-ran the standalone repro. The repro flipped from PASS to FAIL on Case 1, proving it actually exercises the bug condition the fix addresses.

Pre-fix output (with findPluginMethodDescriptor removed):

--- Case 1: workboard.cards.dispatch on http-route surface ---
resolveRequiredOperatorScopeForMethod = undefined
FAIL: AssertionError [ERR_ASSERTION]: expected write scope from http-route surface
+ actual - expected
+ undefined
- 'operator.write'

This matches the user-visible symptom in #92044 exactly: resolveRequiredOperatorScopeForMethod returns undefined, then authorizeOperatorScopesForMethod defaults to operator.admin, and the CLI's ["operator.write", "operator.read"] is rejected.

Post-fix output (this branch):

--- Case 1: workboard.cards.dispatch on http-route surface ---
resolveRequiredOperatorScopeForMethod = operator.write
authorize([operator.write]) = { allowed: true }

Notes for reviewers

Related

🤖 Generated with Claude Code

@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime scripts Repository scripts size: M labels Jun 18, 2026
@openclaw-barnacle openclaw-barnacle Bot added the proof: supplied External PR includes structured after-fix real behavior proof. label Jun 18, 2026
@wangmiao0668000666

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

PR #94343 fixes #92044 (workboard dispatch scope classification). This is the clean-history version that supersedes #94047 (closed).

Summary of changes:

  • src/gateway/method-scopes.ts: cross-surface descriptor lookup helper that walks the active / http-route / channel surfaces so plugin-declared scopes reach the resolver regardless of which surface a request entered.
  • src/gateway/method-scopes.test.ts: 6 new tests covering each surface, priority order, regression for the admin fallback, and sibling coverage for memory-core: dream promotion cron fails with missing scope: operator.admin #78894 (memory-core).
  • scripts/repro/issue-92044-workboard-scope.mjs: standalone live proof script with 5 cases against real production code (no vitest mocks).
  • scripts/repro/issue-92044-workboard-e2e.mjs: production-surface proof showing descriptor counts after setActivePluginRegistry and the resulting scope resolution.
  • test/scripts/lint-suppressions.test.ts: register the new use-unknown-in-catch-callback-variable suppression from the repro script in the explicit allowlist.

Real behavior proof:

  • node --import tsx scripts/repro/issue-92044-workboard-scope.mjs → PASS, 5/5 cases.
  • node --import tsx scripts/repro/issue-92044-workboard-e2e.mjs → PASS.
  • Unit tests: 324 + 20 + 98 + 16 + 4 + 3 pass across method-scopes, gateway methods registry, server-plugins, plugin runtime, workboard gateway, and lint-suppressions test files.
  • Lint / tsgo / build: all clean.

This is the root-cause fix (option a). PR #92066 (option b, workboard CLI removes hardcoded scopes) is complementary and authored separately; this PR makes option b's behavior correct in the server.

Revert test (proof the fix is necessary, not redundant): with findPluginMethodDescriptor removed, Case 1 of the standalone repro flips to FAIL with resolveRequiredOperatorScopeForMethod = undefined. Detailed evidence is in the PR body.

@clawsweeper

clawsweeper Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper

clawsweeper Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed June 19, 2026, 6:53 AM ET / 10:53 UTC.

Summary
The PR changes Gateway request authorization to use the attached method registry's declared static operator scope before falling back to the global method-scope resolver, with a regression test for Workboard dispatch.

PR surface: Source +20, Tests +65. Total +85 across 3 files.

Reproducibility: yes. Source inspection shows current main authorizes Workboard dispatch through the global fallback path before using the attached dispatch registry, while Workboard declares the method as operator.write; I did not run a live gateway in this read-only review.

Review metrics: 1 noteworthy metric.

  • Authorization source: 1 changed. Gateway request authorization now trusts the attached method registry's static operator scope before falling back to global method-scope resolution.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #92044
Summary: This PR is the current root-cause fix candidate for the Workboard dispatch scope bug; the older same-author branch is superseded and the Workboard-only PR is an alternate workaround.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

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 patch intentionally changes the Gateway authorization boundary for registered plugin methods: a non-admin operator can call a method when the attached dispatch registry declares an operator scope such as operator.write instead of falling through to operator.admin.

Maintainer options:

  1. Accept attached registry scopes (recommended)
    Land after maintainers confirm the dispatch registry is the intended source of truth for plugin method authorization.
  2. Audit plugin descriptors first
    Before merge, sample bundled plugin method descriptors to confirm their declared read/write/admin scopes remain appropriate when enforced from the attached registry.
  3. Pause for stricter policy
    If maintainers do not want attached plugin descriptors to lower the fallback admin requirement, pause and design a request-surface-specific authorization policy instead.

Next step before merge

  • No automated repair is needed; maintainers need to accept the Gateway auth-boundary change and land only after exact-head required checks are satisfactory.

Security
Cleared: No supply-chain or concrete security defect was found; the intentional Gateway authorization-boundary change is tracked as merge risk.

Review details

Best possible solution:

Land the attached-registry authorization fix after maintainers accept the auth-boundary change and required exact-head checks pass, then close the linked Workboard bug and retire the Workboard-only workaround path.

Do we have a high-confidence way to reproduce the issue?

Yes. Source inspection shows current main authorizes Workboard dispatch through the global fallback path before using the attached dispatch registry, while Workboard declares the method as operator.write; I did not run a live gateway in this read-only review.

Is this the best way to solve the issue?

Yes. Authorizing against the same attached registry used for dispatch is narrower and cleaner than a Workboard-only CLI workaround or the earlier cross-surface global lookup because handler and scope metadata stay paired.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 92d1f04de340.

Label changes

Label changes:

  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes terminal proof for the reported production-code path, and the latest reviewer comment records exact-head build, check, targeted Vitest, and clean autoreview after the final rewrite.

Label justifications:

  • P1: The linked bug blocks the documented headless Workboard dispatch workflow by treating an operator.write plugin method as admin-only.
  • merge-risk: 🚨 security-boundary: The diff changes Gateway operator authorization by allowing attached plugin registry scopes to replace the historical admin fallback for registered plugin methods.
  • rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦞 diamond lobster and patch quality is 🦞 diamond lobster.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body includes terminal proof for the reported production-code path, and the latest reviewer comment records exact-head build, check, targeted Vitest, and clean autoreview after the final rewrite.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes terminal proof for the reported production-code path, and the latest reviewer comment records exact-head build, check, targeted Vitest, and clean autoreview after the final rewrite.
Evidence reviewed

PR surface:

Source +20, Tests +65. Total +85 across 3 files.

View PR surface stats
Area Files Added Removed Net
Source 2 23 3 +20
Tests 1 65 0 +65
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 3 88 3 +85

What I checked:

  • Repository policy read: Read the full root policy and the scoped Gateway policy; the review applied the Gateway hot-path guidance and the ClawSweeper auth-boundary merge-risk rules. (AGENTS.md:1, 92d1f04de340)
  • Current main behavior: Current main's request authorization calls authorizeOperatorScopesForMethod before the attached method registry is consulted for scope metadata, matching the reported admin fallback path. (src/gateway/server-methods.ts:253, 92d1f04de340)
  • PR implementation: The PR head passes the request's methodRegistry into authorizeGatewayMethod and uses methodRegistry.getScope(method) plus isOperatorScope before falling back to the global resolver. (src/gateway/server-methods.ts:259, 9a4afec6a8c0)
  • Static scope helper: The PR factors required-scope authorization without changing the existing admin short-circuit, write-satisfies-read rule, or missing-scope response shape. (src/gateway/method-scopes.ts:181, 9a4afec6a8c0)
  • Regression coverage: The new test builds an attached registry with workboard.cards.dispatch scoped to operator.write while the global runtime registry is empty, then verifies write is allowed and read is denied with operator.write missing. (src/gateway/server-methods.authorization.test.ts:20, 9a4afec6a8c0)
  • Workboard scope contract: Workboard registers workboard.cards.dispatch with WRITE_SCOPE, and the docs say dispatch requires operator.write or operator.admin while the CLI path uses read/write scopes. (extensions/workboard/src/gateway.ts:384, 92d1f04de340)

Likely related people:

  • vincentkoc: Current-main blame/log in this shallow checkout points the Gateway authorization, method-scope, and registry files through recent Vincent Koc commits, making him a good routing candidate for this auth path. (role: recent area contributor; confidence: medium; commits: ccdec2e294c4, 844f405ac1be; files: src/gateway/server-methods.ts, src/gateway/method-scopes.ts, src/gateway/methods/registry.ts)
  • steipete: Authored the final head commit that rewrote the branch to authorize from the attached registry, is assigned on the PR, and posted land-ready local verification after the force-push. (role: recent branch contributor and reviewer; confidence: high; commits: 9a4afec6a8c0, 73e9e787b4df; files: src/gateway/server-methods.ts, src/gateway/method-scopes.ts, src/gateway/server-methods.authorization.test.ts)
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.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. 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: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. labels Jun 18, 2026
@wangmiao0668000666

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

P3 finding addressed in commit 2acbbb2:

  • Reworded scripts/repro/issue-92044-workboard-e2e.mjs:2-4 to be accurate
  • Script now correctly states it builds a synthetic registry mirroring
    the workboard plugin's descriptor registration, then runs the same
    production resolver path
  • node --import tsx scripts/repro/issue-92044-workboard-e2e.mjs still PASS
    after the comment change (verified locally)

No code-path changes; comment + wording only. PR remains at 🐚 platinum
hermit / ready for maintainer look. Base refresh is a maintainer
decision at merge time; not rebase-chasing pre-merge.

@clawsweeper

clawsweeper Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jun 18, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. labels Jun 18, 2026
@wangmiao0668000666

Copy link
Copy Markdown
Contributor Author

@steipete As the workboard owner, could you please review this PR? It fixes the critical scope resolution bug (#92044) that was preventing from working correctly.

@vincentkoc You've been very active recently with Gateway-related fixes. Could you also take a look at this method-scopes resolution fix?

The PR has:

  • ✅ Diamond lobster rating (very high readiness)
  • ✅ Proof: sufficient (ClawSweeper approved)
  • ✅ P1 priority (high-priority user-facing bug)
  • ✅ Ready for maintainer look status
  • ✅ All tests passing (324+ tests)
  • ✅ Clean reproduction scripts

This is a focused fix for the Gateway scope resolution that affects workboard and other plugins. Thanks!

wangmiao0668000666 and others added 5 commits June 19, 2026 10:52
…closes openclaw#92044)

Plugin-registered gateway methods were silently requiring operator.admin
because resolveScopedMethod only consulted activeRegistry.gatewayMethodDescriptors.
Plugin descriptors may live in the http-route or channel surface instead,
and authorizeOperatorScopesForMethod fell through to the admin default
when the active surface missed the descriptor.

Look across all three active surfaces (active, http route, channel) so
plugin-declared scopes reach the resolver regardless of which surface a
request entered. Active surface still wins when it has the descriptor.
The admin fallback for unknown methods is preserved.

Sibling coverage for openclaw#78894 (memory-core dream-promotion cron) confirms
the same fix path works for any plugin that uses api.registerGatewayMethod.

- src/gateway/method-scopes.ts: cross-surface descriptor lookup helper
- src/gateway/method-scopes.test.ts: 3 surface + 1 regression + 2 sibling tests
- scripts/repro/issue-92044-workboard-scope.mjs: standalone live proof
…wlist

The standalone repro script for openclaw#92044 (scripts/repro/issue-92044-workboard-scope.mjs)
suppresses typescript/use-unknown-in-catch-callback-variable on its main().catch()
handler because the script is plain JS (.mjs) and cannot carry the type annotation
oxlint would normally expect. Register the suppression in the explicit allowlist
that lint-suppressions.test.ts enforces so the tooling CI gate stays green.
…face counts

Standalone proof that setActivePluginRegistry syncs a plugin descriptor
across all three active surfaces (active / httpRoute / channel), and that
resolveRequiredOperatorScopeForMethod reaches the declared scope through
the production code path the gateway server uses. Surfaces the gap that
a unit-test-only proof can leave open.
@steipete
steipete force-pushed the fix/workboard-scope-classification-92044-clean branch from 2acbbb2 to 9a4afec Compare June 19, 2026 10:46
@steipete
steipete requested a review from a team as a code owner June 19, 2026 10:46
@steipete

Copy link
Copy Markdown
Contributor

Land-ready verification:

  • Rebased onto origin/main at 3091c13713f.
  • pnpm build: passed (Node 24.16.0).
  • pnpm check: passed.
  • node scripts/run-vitest.mjs src/gateway/method-scopes.test.ts src/gateway/server-methods.authorization.test.ts: 302 tests passed.
  • Fresh Codex autoreview: clean; no accepted/actionable findings.
  • Removed the two one-off issue reproduction scripts; authorization now uses the exact registry attached to dispatch.

Thanks @wangmiao0668000666.

@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jun 19, 2026
@steipete
steipete merged commit 27f702d into openclaw:main Jun 19, 2026
50 of 57 checks passed
@wangmiao0668000666

Copy link
Copy Markdown
Contributor Author

🎉 So happy to see PR #94343 merged — and even more so to see it landed by @steipete himself! Huge thanks for taking the time to rebase, run verification, and clean up the commits. Your "Land-ready verification" was a great learning moment for me — deleting the one-off repro scripts and having authorization flow through the dispatch-time attached registry is exactly the cleaner design, and watching you tighten it up at merge time taught me more than the original PR work did.

Also thanks to @vincentkoc for the steady Gateway-area work that helped frame where this fix belongs.

Each contribution teaches me something new. This round was all about the subtle invariants between attached-registry scope resolution vs the global resolver — and how easy it is to drift toward a "fix the CLI instead of fixing the seam" workaround when the symptom happens to surface in one plugin.

Contributing to OpenClaw is genuinely fun, even when the reviewer bot makes me re-prove things 😄. I'll keep going — looking forward to the next opportunity to give back 🤖🦞

Pick-cat added a commit to Pick-cat/openclaw that referenced this pull request Jun 20, 2026
…gistered methods

Selecting opts.methodRegistry unconditionally dropped late-registered plugin
RPC methods; an earlier revision replaced it outright, which regressed the
attached-registry authorization path (openclaw#94343). Prefer the attached registry
only when it owns the requested method, otherwise rebuild from the live plugin
registry so late-registered plugin methods (openclaw#94127) stay reachable.

Adds scripts/proof-gateway-plugin-dispatch.mts as a live runtime proof harness.
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jun 20, 2026
…aw#94343)

Authorize plugin gateway methods against the exact registry attached to dispatch, preserving fallback behavior for dynamic methods and deleting one-off repro scripts.

Fixes openclaw#92044.

Co-authored-by: wangmiao0668000666 <[email protected]>
Pick-cat added a commit to Pick-cat/openclaw that referenced this pull request Jun 22, 2026
…gistered methods

Selecting opts.methodRegistry unconditionally dropped late-registered plugin
RPC methods; an earlier revision replaced it outright, which regressed the
attached-registry authorization path (openclaw#94343). Prefer the attached registry
only when it owns the requested method, otherwise rebuild from the live plugin
registry so late-registered plugin methods (openclaw#94127) stay reachable.

Adds scripts/proof-gateway-plugin-dispatch.mts as a live runtime proof harness.
Pick-cat added a commit to Pick-cat/openclaw that referenced this pull request Jun 23, 2026
…gistered methods

Selecting opts.methodRegistry unconditionally dropped late-registered plugin
RPC methods; an earlier revision replaced it outright, which regressed the
attached-registry authorization path (openclaw#94343). Prefer the attached registry
only when it owns the requested method, otherwise rebuild from the live plugin
registry so late-registered plugin methods (openclaw#94127) stay reachable.

Adds scripts/proof-gateway-plugin-dispatch.mts as a live runtime proof harness.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gateway Gateway runtime merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. P1 High-priority user-facing bug, regression, or broken workflow. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. size: S status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: openclaw workboard dispatch fails with missing scope: operator.admin though the method is registered operator.write

2 participants