← Back to PRs

#22666: fix(gateway): operator.admin should imply all operator scopes

by maximveksler open 2026-02-21 13:41 View on GitHub →
size: S
## Summary - `operatorScopeSatisfied()` in `operator-scope-compat.ts` only treated `operator.admin` as implying `operator.read`, but **not** `operator.write`, `operator.approvals`, or `operator.pairing` - This contradicted `authorizeOperatorScopesForMethod()` in `method-scopes.ts` which correctly treats `operator.admin` as a superscope that bypasses all scope checks - The inconsistency caused devices paired with `operator.admin` to enter a "scope-upgrade" re-pairing loop when connecting with `operator.write`, producing repeated `1008 pairing required` WebSocket errors ## Fix Check for `operator.admin` first in `operatorScopeSatisfied()`, returning `true` for any requested operator scope — matching the behavior already established in per-method authorization. ## Test plan - [x] Updated existing test that asserted the broken behavior (`"keeps non-read operator scopes explicit"` → `"treats operator.admin as superscope for all operator scopes"`) - [x] Added coverage for all operator scopes being satisfied by `operator.admin` - [x] Added coverage for multi-scope requests with only `operator.admin` granted - [x] Added negative test: non-admin scopes don't imply each other - [x] Verified `method-scopes.test.ts` still passes (no regression) 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- greptile_comment --> <h3>Greptile Summary</h3> Fixed scope hierarchy bug where `operator.admin` didn't imply all operator scopes during device connection validation. The fix moves the admin scope check to the top of `operatorScopeSatisfied()` in `operator-scope-compat.ts:18-20`, matching the existing behavior in `authorizeOperatorScopesForMethod()` at `method-scopes.ts:178-179`. This eliminates the re-pairing loop that occurred when devices with `operator.admin` tried to connect with `operator.write`, `operator.approvals`, or `operator.pairing` scopes. **Changes:** - `operatorScopeSatisfied()` now checks for `operator.admin` first and returns true for any requested operator scope - Test suite updated with comprehensive coverage for all operator scopes being satisfied by `operator.admin` - Added negative test to confirm non-admin scopes don't imply each other **Impact:** The fix resolves a critical authentication issue that caused `1008 pairing required` WebSocket errors for admin devices requesting non-read scopes. <h3>Confidence Score: 5/5</h3> - This PR is safe to merge with minimal risk - The fix is well-contained, logically sound, and aligns with existing authorization patterns in the codebase. The change makes `operatorScopeSatisfied()` consistent with `authorizeOperatorScopesForMethod()`, both treating `operator.admin` as a superscope. Test coverage is comprehensive with positive and negative test cases, and the implementation is a simple early-return guard that doesn't affect other code paths. - No files require special attention <sub>Last reviewed commit: 8ff56fe</sub> <!-- greptile_other_comments_section --> <sub>(4/5) You can add custom instructions or style guidelines for the agent [here](https://app.greptile.com/review/github)!</sub> <!-- /greptile_comment -->

Most Similar PRs