Skip to content

test(gateway): pin plugin auth:gateway gutted-posture tripwire (#2724)#2726

Merged
alexey-pelykh merged 1 commit into
mainfrom
test/plugin-gateway-auth-tripwire-2724
Jun 17, 2026
Merged

test(gateway): pin plugin auth:gateway gutted-posture tripwire (#2724)#2726
alexey-pelykh merged 1 commit into
mainfrom
test/plugin-gateway-auth-tripwire-2724

Conversation

@alexey-pelykh

Copy link
Copy Markdown

What

Adds a behavioral gutted-posture tripwire for the plugin-route gateway-auth perimeter — a new test file (src/gateway/server.plugin-gateway-auth-tripwire.test.ts, 2 tests). No production changes.

Why

RemoteClaw deliberately guts the plugin-route gateway-auth perimeter: buildPluginRequestStages in server-http.ts hardcodes gatewayAuthSatisfied = true ("always pass") instead of calling the removed enforcePluginRouteGatewayAuth.

That gut is not a clean unauth bypass on its own. An auth: "gateway" plugin route stays unreachable only because a second, independent guard in createGatewayPluginRequestHandler refuses to dispatch when gatewayRequestOperatorScopes is undefined — and buildPluginRequestStages forwards gatewayAuthSatisfied but never the operator scopes.

The safety is therefore emergent from two half-disabled mechanisms. A future upstream sync that re-couples scope propagation while leaving gatewayAuthSatisfied = true would silently re-open the perimeter. The existing unit tests in server/plugins-http.test.ts exercise that guard in isolation (they pass the dispatch context directly), so they cannot catch a regression in the server-pipeline wiring that feeds it.

How

  • Negative tripwire — drives an auth: "gateway" route through the real server pipeline and asserts it stays blocked, anchoring on the guard's blocked without caller scope context log to prove the block happens at the scope guard (not a perimeter 401, not guard 1). Verified non-vacuous: it fails by design when scope propagation is re-coupled at server-http.ts:353.
  • Positive companion — injects operator scopes to prove the path is genuinely live end-to-end, so the negative assertion cannot pass for the wrong reason (e.g. broken wiring). The pair discriminates three states: gutted → blocked, scoped → reachable, broken-wiring → neither.

The test runs in the gateway behavioral suite enabled in #2720, so it gates every PR. It is documented in-file as a DIFF-SYNC re-introduction guard: if it fails after an upstream sync, restore the gutted-posture — do not weaken the test.

One item from #2724.

🤖 Generated with Claude Code

The plugin-route gateway-auth perimeter is deliberately gutted (always-pass) in the fork. An auth:"gateway" route stays unreachable only because buildPluginRequestStages forwards gatewayAuthSatisfied=true WITHOUT operator scopes, so the second guard in createGatewayPluginRequestHandler still blocks dispatch. That safety is emergent from two half-disabled mechanisms — a sync re-coupling scope propagation would silently re-open it (security-architect flag during #2720).

The guard's unit tests cover it in isolation; this adds a black-box integration test pinning the server-pipeline wiring (gut -> guard) end-to-end, plus a positive companion proving the path stays live (so the negative assertion cannot pass vacuously). Verified non-vacuous: the tripwire fails by design when scope propagation is re-coupled at server-http.ts:353. Runs in the gateway suite enabled by #2720, so it gates every PR. DIFF-SYNC re-introduction guard (hq-internal ADR 0010/0011 family).

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@alexey-pelykh
alexey-pelykh enabled auto-merge (squash) June 17, 2026 14:53
@alexey-pelykh
alexey-pelykh merged commit f7cf650 into main Jun 17, 2026
17 checks passed
@alexey-pelykh
alexey-pelykh deleted the test/plugin-gateway-auth-tripwire-2724 branch June 17, 2026 15:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant