Repository navigation
fix(mcp): attach folder assignments through IAP and the agent gate - #83
Merged
Merged
Conversation
import --mcp skipped the CLI egress chain, so IAP 403'd folder reads while REST succeeded. The production allowlist then hid get_workflow_details from the same CLI. Run client middlewares on MCP and let a verified impersonator read folders the agent policy withholds. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
import --mcpthrough the n8n-cli proxy now actually attaches folder assignments (parentFolderId/folder). Two hops were missing from the existing CLI → proxy → mock stack, and both had to fail in the same way production did before the path was real.The public REST API never returns which folder a workflow sits in, so import reads that assignment over n8n's instance-level MCP server. That MCP call left the machine through a raw
fetch, while REST and webhook already ranctx.clientMiddlewares(iap-auth,impersonator-token). Against an authenticating gateway the REST import succeeded and MCP 403'd with IAP HTML — JSON was written with no folder keys. The CLI still sends no MCPAuthorizationin proxy mode; the proxy injects the token on/mcp-server/*.Fixing IAP is not enough on its own. Production n8n-proxy gates MCP for agents (
N8N_MCP_ALLOW_TOOLS=search_workflows,get_workflow_entry,execute_workflow, noget_workflow_details, search narrowed to in-policy workflows). The same CLI talking through that gate still got a successful REST import and JSON with no folder keys: search omitted the untagged workflow andget_workflow_detailscame backUnknown tool. A verified impersonator (oauth-verifytrusted Cloud Run bearer +impersonator-verify) is an operator, not an agent, so folder-read verbs (search_workflows,get_workflow_details,search_folders) skip the allowlist and the search filter for that caller.execute_workflowstays gated. A spoofedX-Impersonator-Id-Tokenwithout a verifier does not count.The operator-identity probe runs only identity-populating middlewares.
project-roleandauthzneed a workflow this probe does not have — they would deny the lookup itself, or hit Zeus on everyinitialize.Deploy: live
import --mcpagainst current n8n-proxy also needs this proxy binary. The CLI IAP fix alone cannot attach folders while production still serves the old gate.Bump to 2.23.0.
Motivation
#82 added folder membership as code, with
import --mcpas the only read path for a write-only REST field. The proxy already had bearer-token-inject for/mcp-server/*and the CLI already had IAP egress for webhook. Neither was wired to MCP, and the existing integration tests never stood an IAP front door or a production-like agent allowlist in front of the proxy — so token-inject stayed green while production wrote JSON with noparentFolderId/folder. Teams using n8n-workflows' folder-as-code import cannot place files until this hop is the same one REST already takes, and until the agent gate does not strip operator folder reads.Test plan
make quality-gate(generate-schemas, typecheck, lint, check-third-party-licenses,bun test) — 1955 passbun test tests/integration— CLI → [IAP] → proxy → mock, includingimport --mcpfolder readsmake build+ size-checkiap-auth+ proxy inject writesparentFolderId/folderon JSON; MCP through IAP carries no MCPAuthorizationget_workflow_detailsis unknown — silent missing keys)oauth-verify+impersonator-verify: Cloud Run Bearer + impersonator token unlocksget_workflow_details; MCP Bearer does not; SA Bearer without impersonator does not; spoofed header without a verifier does not;authzthat would deny a bodyless probe does not strip operator folder reads;execute_workflowstays gated