fix(gateway): narrow plugin route runtime scopes#58167
Conversation
Greptile SummaryThis PR narrows the runtime OAuth scope for plugin-owned HTTP routes from Key changes:
Confidence Score: 5/5Safe to merge; the core change is a single-line scope selection with correct logic and two complementary test suites that lock in the intended behavior. All remaining findings are P2. The logic change is minimal and correct: requiresGatewayAuth is already computed before the runtime client is created and correctly reflects whether any matched route requires gateway auth. The test rewrite removes fragile mocks and asserts directly on observable state. No P0 or P1 issues found. No files require special attention.
|
| Filename | Overview |
|---|---|
| src/gateway/server/plugins-http.ts | Core change: createPluginRouteRuntimeClient now accepts requiresGatewayAuth and maps plugin-auth routes to READ_SCOPE while gateway-auth routes keep WRITE_SCOPE. Logic is correct and minimal. |
| src/gateway/server/plugins-http.runtime-scopes.test.ts | New regression test file. Correctly verifies the behavioral contract: plugin-auth routes fail closed when write-helper access is attempted, and gateway-auth routes retain write-helper access. |
| src/gateway/server/plugins-http.test.ts | Heavy mock infrastructure replaced with a lightweight scope-capture helper. Tests now assert on actual scope values rather than downstream permission failure side-effects. |
| CHANGELOG.md | Changelog entry added to the correct section, accurately describing the scope narrowing change. |
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/gateway/server/plugins-http.runtime-scopes.test.ts
Line: 48
Comment:
**Partial log stub bypasses type safety**
`{ warn: vi.fn() }` is cast with `as` to the full `SubsystemLogger` type, so any invocation of a non-stubbed method (e.g. `info`, `error`, `debug`) would throw at runtime and produce a confusing test failure rather than a clear type error. `plugins-http.test.ts` avoids this by using `as unknown as PluginHandlerLog`; a consistent pattern here would be safer.
```suggestion
const log = { warn: vi.fn(), info: vi.fn(), error: vi.fn(), debug: vi.fn() } as Parameters<typeof createGatewayPluginRequestHandler>[0]["log"];
```
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "test(gateway): cover plugin route runtim..." | Re-trigger Greptile
363cd87 to
863ef68
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 67b6068b40
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| function createPluginRouteRuntimeClient( | ||
| requiresGatewayAuth: boolean, | ||
| ): GatewayRequestOptions["client"] { | ||
| const scopes = requiresGatewayAuth ? [WRITE_SCOPE] : []; |
There was a problem hiding this comment.
Grant read scope for plugin-auth runtime clients
Using an empty scope array for non-gateway plugin routes removes all operator privileges, not just write access. In this codebase, read methods still require operator.read (see authorizeOperatorScopesForMethod), so plugin-auth webhook handlers that call read-only runtime helpers (for example, subagent paths that dispatch sessions.get) will now fail with missing scope: operator.read and return 500s. This change narrows more than intended; plugin-auth routes need a read scope rather than no scope.
Useful? React with 👍 / 👎.
* wip(gateway): preserve plugin route scope progress * test(gateway): cover plugin route runtime scopes * test(gateway): finish plugin route scope rebase * fix(gateway): drop scopes from plugin-auth routes
* wip(gateway): preserve plugin route scope progress * test(gateway): cover plugin route runtime scopes * test(gateway): finish plugin route scope rebase * fix(gateway): drop scopes from plugin-auth routes
* wip(gateway): preserve plugin route scope progress * test(gateway): cover plugin route runtime scopes * test(gateway): finish plugin route scope rebase * fix(gateway): drop scopes from plugin-auth routes
* wip(gateway): preserve plugin route scope progress * test(gateway): cover plugin route runtime scopes * test(gateway): finish plugin route scope rebase * fix(gateway): drop scopes from plugin-auth routes
* wip(gateway): preserve plugin route scope progress * test(gateway): cover plugin route runtime scopes * test(gateway): finish plugin route scope rebase * fix(gateway): drop scopes from plugin-auth routes
* wip(gateway): preserve plugin route scope progress * test(gateway): cover plugin route runtime scopes * test(gateway): finish plugin route scope rebase * fix(gateway): drop scopes from plugin-auth routes
* wip(gateway): preserve plugin route scope progress * test(gateway): cover plugin route runtime scopes * test(gateway): finish plugin route scope rebase * fix(gateway): drop scopes from plugin-auth routes
Summary
auth: "plugin"routes to read scope, keepauth: "gateway"routes on write scope, and add regression coverage that proves write-helper access fails closed on plugin-auth routes.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
Root Cause / Regression History (if applicable)
git blame, prior PR, issue, or refactor if known): the current branch preserves the existing route-scope fix work and adds a tighter regression guardrail on top.Regression Test Plan (if applicable)
src/gateway/server/plugins-http.runtime-scopes.test.tsUser-visible / Behavior Changes
Plugin-owned HTTP routes that use plugin auth no longer get write-capable runtime helper access by default. Gateway-authenticated plugin routes keep the existing write-capable runtime behavior.
Diagram (if applicable)
Security Impact (required)
No)No)No)No)Yes)Yes, explain risk + mitigation: plugin-auth HTTP routes now run with the narrower read scope, while gateway-auth routes keep write scope. Coverage locks the intended split in place.Repro + Verification
Environment
Steps
Expected
Actual
Evidence
Human Verification (required)
pnpm check, andpnpm buildon the rebased tree.pnpm check, andpnpm buildwas blocked by host-level process contention during this session.Review Conversations
Compatibility / Migration
Yes)No)No)Risks and Mitigations
AI-assisted: yes. Testing: targeted regression coverage added; local verification attempted as noted above.