Skip to content

fix(gateway): re-check allowedSessionKeyPrefixes after /hooks agent-rebind (#2723)#2730

Merged
alexey-pelykh merged 1 commit into
mainfrom
fix/gateway-hooks-rebind-prefix-recheck-2723
Jun 18, 2026
Merged

fix(gateway): re-check allowedSessionKeyPrefixes after /hooks agent-rebind (#2723)#2730
alexey-pelykh merged 1 commit into
mainfrom
fix/gateway-hooks-rebind-prefix-recheck-2723

Conversation

@alexey-pelykh

Copy link
Copy Markdown

Summary

Fixes #2723 — a gateway authz-confinement gap. The /hooks/agent and
/hooks/<mapping> paths validated the requested session key against
hooks.allowedSessionKeyPrefixes, then rebound it to the target agent
(agent:main:*agent:hooks:*) via normalizeHookDispatchSessionKey and
dispatched without re-checking the rebound key. An authenticated hook caller
could therefore rebind a turn into a session namespace it was never authorized
for: e.g. with allowlist ["hook:", "agent:main:"], a request for
sessionKey: "agent:main:..." + agentId: hooks passed the pre-rebind check,
then rebound to agent:hooks:... (which matches neither prefix) and dispatched.

Fix

  • Add resolveHookDispatchSessionKey (src/gateway/hooks.ts): rebinds the
    session key to the target agent, then re-validates the rebound key against
    allowedSessionKeyPrefixes. Returns the existing {ok,value}|{ok,error}
    result shape used by resolveHookSessionKey.
  • Gate both ingress paths in createHooksRequestHandler
    (src/gateway/server-http.ts) on it — reject 400 with the existing
    getHookSessionKeyPrefixError message when the rebound key violates the
    allowlist. Single security chokepoint; dispatchAgentHook has no other
    production invoker.

Behavior change

This tightens behavior: post-rebind requests whose rebound key violates the
prefix allowlist now return 400 instead of being accepted. Requests are
unaffected when no allowlist is configured, or when the rebound key still
matches an allowed prefix.

Tests

  • Restored the two covering integration tests that were removed during the
    CI-green test-remediation pass (the documented deferral lived in
    src/gateway/server.hooks.test.ts, not hooks.test.ts as the issue text
    states): agent-path + mapping-path "rejects rebinding into a disallowed
    namespace" — both assert 400 + "sessionKey must start with one of" +
    cronIsolatedRun not called. Confirmed RED before the fix, GREEN after.
  • Added a unit test for resolveHookDispatchSessionKey in hooks.test.ts
    (blocked + allowed cases).
  • The idempotency replay-cache tests in the same removed hunk are intentionally
    out of scope (net-new feature, separate BACKLOG item) and left unrestored;
    the BACKLOG comment documenting them is preserved.

Verification

  • pnpm test:gateway — 1557 pass / 9 skip / 0 fail (full gateway suite, no regressions)
  • pnpm check — format + typecheck + lint + css-drift all clean
  • Fork-integrity gates (throwing-stub-callers, zombie-imports, stub-debt, obsolescence) all pass

Acceptance criteria

  • Post-rebind requests whose rebound session key violates the prefix allowlist are rejected.
  • The documented server.hooks.test.ts cases are restored and pass.

🤖 Generated with Claude Code

…ebind (#2723)

The /hooks/agent and /hooks/<mapping> paths validated the requested session key
against hooks.allowedSessionKeyPrefixes, then rebound it to the target agent
(agent:main:* -> agent:hooks:*) and dispatched without re-checking — an
authenticated hook caller could rebind a turn into a session namespace it was
never authorized for (an authz-confinement gap).

Add resolveHookDispatchSessionKey, which rebinds then re-validates the dispatch
key against the allowlist, and gate both ingress paths on it (reject 400 on
violation). Restore the two covering integration tests (agent + mapping path)
removed during the CI-green test-remediation pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@alexey-pelykh
alexey-pelykh merged commit aa198e4 into main Jun 18, 2026
17 checks passed
@alexey-pelykh
alexey-pelykh deleted the fix/gateway-hooks-rebind-prefix-recheck-2723 branch June 18, 2026 08:41
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.

gateway: /hooks agent-rebind does not re-check allowedSessionKeyPrefixes after remapping the session key

1 participant