Executor version
Executor Cloud (hosted, executor.sh), tested 2026-08-26. Same toolkit routing code path as the /mcp/toolkits/<slug> endpoints.
Summary
Workspace tool policies (require_approval) are enforced on the base /mcp endpoint but are silently skipped on toolkit-scoped endpoints (/mcp/toolkits/<slug>). A tool that is gated behind an approval policy at the workspace level runs immediately, with no pause and no approval prompt, when the same call is made through a toolkit endpoint. The approval mode is irrelevant — URL approval, native elicitation, and model-side approval all bypass equally on toolkit endpoints.
Because toolkits are the mechanism for handing a curated tool set to a team, this means policy governance is absent on exactly the surface where least-privilege delegation is expected to apply.
Reproduction
- Create a workspace (
org-owned) policy: require_approval on a read tool, e.g. <integration>.contacts.getById (also tested with an embedded-wildcard pattern <integration>.*.*.contacts.getById). Confirm it appears under Active policies, scoped to Workspace.
- Via the
execute meta-tool on the base /mcp endpoint, call that tool.
- Via the
execute meta-tool on a toolkit endpoint /mcp/toolkits/<slug> bound to the same workspace/connection, call the identical tool with the identical arguments.
Expected
Both endpoints evaluate the workspace policy and pause the execution for approval (waiting_for_interaction + executionId), regardless of endpoint scope.
Actual
| Endpoint |
Approval mode |
Result |
base /mcp |
URL approval |
✅ Pauses → approval URL → decline propagates and blocks the call |
base /mcp |
native elicitation |
⚠️ Execution errors on the elicitation step against a client that does not advertise the elicitation capability (separate issue, noted below) |
/mcp/toolkits/<slug> |
native approval |
❌ Runs immediately, returns full record, no pause |
/mcp/toolkits/<slug> |
URL approval |
❌ Runs immediately, returns full record, no pause |
/mcp/toolkits/<slug> |
model approval |
❌ Runs immediately, returns full record, no pause |
On the base endpoint the policy fired correctly and a user decline propagated back as a blocked tool call. On every toolkit endpoint the same gated call returned the underlying record (which in our case contained third-party PII) with no policy evaluation at all. Reproduced repeatedly across all three toolkit approval modes.
Analysis / likely cause
The policy check appears to be wired into the executor constructed for the default /mcp resource but not into the toolkit-scoped executor built in createConfigForResource for resource.kind !== "default". The toolkit executor resolves the same connections and dispatches tools, but the workspace-policy guard that gates dispatch on the base path is not applied on the toolkit path — so require_approval (and, by extension, very likely block) is not evaluated for toolkit-scoped invocations.
This is the same class of defect as #1384 (an authorization gate — there, granted OAuth scope — that exists in configuration but is never evaluated at dispatch), and it fits the pattern in #1520 where toolkit MCP endpoints diverge from the base endpoint's behaviour in another subsystem. It is distinct from #1618 / #1406, which are local-daemon 500s on toolkit routes (there the toolkit route fails closed; here it fails open).
Impact
- Governance bypass: any workspace
require_approval policy can be circumvented by routing the call through a toolkit endpoint. Since agents call tools through execute by default, this is the normal path, not an edge case.
- Likely affects
block too: if the guard isn't consulted on toolkit dispatch, "blocked" tools may also be reachable via toolkit endpoints (not yet tested — flagging for the maintainer).
- Least-privilege inversion: toolkits are the intended delegation surface for teams, so the one place a workspace owner most expects policy to hold is the one place it doesn't.
Suggested fix
Apply the same workspace/policy guard used for the default resource when constructing the toolkit-scoped executor in createConfigForResource, and add a regression test that (a) sets a require_approval policy and (b) asserts a toolkit-endpoint invocation of the gated tool pauses rather than dispatching. Worth also asserting block on a toolkit endpoint.
Secondary observation (separate, minor)
On the base /mcp endpoint, the native elicitation approval mode errors the execution when the connected MCP client does not advertise the elicitation capability, rather than falling back to a URL/redirect approval or returning a clear "client cannot approve" result. URL approval is unaffected and is the safe default for clients without elicitation support. Happy to split this into its own issue if useful.
Created via ASI MCP
Requested by: lvickery@asi.co.nz
Session: dec48a1d807caa26f9b5c959033ec9dc3f5a97f7706fb0767998f69d8164ad7b
Executor version
Executor Cloud (hosted, executor.sh), tested 2026-08-26. Same toolkit routing code path as the
/mcp/toolkits/<slug>endpoints.Summary
Workspace tool policies (
require_approval) are enforced on the base/mcpendpoint but are silently skipped on toolkit-scoped endpoints (/mcp/toolkits/<slug>). A tool that is gated behind an approval policy at the workspace level runs immediately, with no pause and no approval prompt, when the same call is made through a toolkit endpoint. The approval mode is irrelevant — URL approval, native elicitation, and model-side approval all bypass equally on toolkit endpoints.Because toolkits are the mechanism for handing a curated tool set to a team, this means policy governance is absent on exactly the surface where least-privilege delegation is expected to apply.
Reproduction
org-owned) policy:require_approvalon a read tool, e.g.<integration>.contacts.getById(also tested with an embedded-wildcard pattern<integration>.*.*.contacts.getById). Confirm it appears under Active policies, scoped to Workspace.executemeta-tool on the base/mcpendpoint, call that tool.executemeta-tool on a toolkit endpoint/mcp/toolkits/<slug>bound to the same workspace/connection, call the identical tool with the identical arguments.Expected
Both endpoints evaluate the workspace policy and pause the execution for approval (
waiting_for_interaction+executionId), regardless of endpoint scope.Actual
/mcp/mcpelicitationcapability (separate issue, noted below)/mcp/toolkits/<slug>/mcp/toolkits/<slug>/mcp/toolkits/<slug>On the base endpoint the policy fired correctly and a user decline propagated back as a blocked tool call. On every toolkit endpoint the same gated call returned the underlying record (which in our case contained third-party PII) with no policy evaluation at all. Reproduced repeatedly across all three toolkit approval modes.
Analysis / likely cause
The policy check appears to be wired into the executor constructed for the default
/mcpresource but not into the toolkit-scoped executor built increateConfigForResourceforresource.kind !== "default". The toolkit executor resolves the same connections and dispatches tools, but the workspace-policy guard that gates dispatch on the base path is not applied on the toolkit path — sorequire_approval(and, by extension, very likelyblock) is not evaluated for toolkit-scoped invocations.This is the same class of defect as #1384 (an authorization gate — there, granted OAuth scope — that exists in configuration but is never evaluated at dispatch), and it fits the pattern in #1520 where toolkit MCP endpoints diverge from the base endpoint's behaviour in another subsystem. It is distinct from #1618 / #1406, which are local-daemon 500s on toolkit routes (there the toolkit route fails closed; here it fails open).
Impact
require_approvalpolicy can be circumvented by routing the call through a toolkit endpoint. Since agents call tools throughexecuteby default, this is the normal path, not an edge case.blocktoo: if the guard isn't consulted on toolkit dispatch, "blocked" tools may also be reachable via toolkit endpoints (not yet tested — flagging for the maintainer).Suggested fix
Apply the same workspace/policy guard used for the default resource when constructing the toolkit-scoped executor in
createConfigForResource, and add a regression test that (a) sets arequire_approvalpolicy and (b) asserts a toolkit-endpoint invocation of the gated tool pauses rather than dispatching. Worth also assertingblockon a toolkit endpoint.Secondary observation (separate, minor)
On the base
/mcpendpoint, the native elicitation approval mode errors the execution when the connected MCP client does not advertise theelicitationcapability, rather than falling back to a URL/redirect approval or returning a clear "client cannot approve" result. URL approval is unaffected and is the safe default for clients without elicitation support. Happy to split this into its own issue if useful.Created via ASI MCP
Requested by: lvickery@asi.co.nz
Session: dec48a1d807caa26f9b5c959033ec9dc3f5a97f7706fb0767998f69d8164ad7b