Skip to content

Stop a scoped connection key from widening through the Executor app - #78

Merged
shuv1337 merged 2 commits into
v2from
cursor/connection-key-scope-7a98
Nov 5, 2026
Merged

shuv1337 merged 2 commits into
v2from
cursor/connection-key-scope-7a98

Conversation

@shuv1337

@shuv1337 shuv1337 commented Nov 5, 2026 •

Copy link
Copy Markdown
Owner

Hole

#77 refuses an Executor app self-call that widens past the calling connection, but only when x-executor-caller-connection is present. A scoped connection key's one-hop mcpConnections.create was covered. A nested tools.call was not: the Executor app posts to /apps/:app/tools/call with the managed key and the header, and that handler ignored the header. The nested invocation ran as fullAuthority with no connection, so create, mint, and a call to an app outside the connection succeeded for an org admin.

Fix

The organization API, for a request that carries the host-attached connection, narrows tool authority to that connection and stamps the connection on the caller. A nested app invocation therefore stays bound, and tools.call to an out-of-scope app is refused before it runs. A nested OrganizationForbidden stays HTTP 403. Facet workers receive the same connection on their outbound. A managed credential that would replace a different connection is refused. Workflow bodies still do not carry the connection; that is noted on the workflow caller.

A connection that grants every tool of its apps can still create a narrower connection and mint inside it. Browser sessions, full API grants, and unmanaged API keys are unchanged when they do not send the header. A connection key used directly on the API remains ConnectionKeyRefused.

Verify

mcp-connections.spec.ts

bun run e2e:self-host --test-name "connection key cannot widen"

With the API bind in place: pass. nestedWiden, nestedMint, and directMesh are OrganizationForbidden / 403, as an org admin.

With that bind removed (the header is ignored): fail. nestedWiden returns ok: true and creates the wider connection.

After deploy, as the org admin, with an Executor-only connection key at that connection's MCP URL, run tools.call for mcpConnections.create with an extra app, mcpConnections.mintKey on a connection outside the scope, and tools.call of an out-of-scope app. All three must be 403. Revoke the probe connection so its keys are deleted.

Open in Web Open in Cursor 

cursoragent and others added 2 commits November 5, 2026 06:59
A connection key's Executor app self-call uses the caller's full managed key. The calling connection was taken only from caller, which a build that does not declare callerIdentity never receives, so create and mint ran with that full key for org admins too. The connection now travels beside caller, and the app worker is named by it so a warm worker from another connection cannot serve the call.

Co-authored-by: shuv <shuv1337@users.noreply.github.com>
A scoped key's Executor app could call tools.call with the managed key. That API request ignored the calling connection, so the nested invocation was unbound and create, mint, and out-of-scope app calls succeeded. The organization API now narrows to that connection and stamps it on the caller. Facet workers get the same connection on their outbound.

Co-authored-by: shuv <shuv1337@users.noreply.github.com>
@shuv1337
shuv1337 merged commit ade7a40 into v2 Nov 5, 2026
3 checks passed
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.

2 participants