Security at the Boundary

mksglu/context-mode places powerful operations behind a context boundary: it can run code, read files, fetch URLs, index data, and retain session evidence. This chapter asks a narrower security question about that design: which actions are merely redirected to protect context, which are denied by policy, and which controls keep the remaining execution surface within the user’s intended authority? The answer gives operators a way to verify the system without mistaking a concise response for a complete sandbox.

A redirect is not a security block

The first distinction is conceptual, but it has direct security consequences. When context-mode redirects a WebFetch call or a curl command that would pour a response into stdout, the original route is being replaced by another supported route. The alternative context-mode tool is expected to perform the fetch or computation and return a controlled result. The request has not become impossible; it has changed owners at the dataflow boundary.

A true policy denial is different. If a command matches a user-configured deny rule, or a file path violates the project boundary, the correct outcome is to stop and explain the rule. Treating that denial as a suggestion to try another path could turn a deliberate security policy into a routing hint. Context-mode’s routing ADR records this distinction because the agent reads the reason in order to choose its next action. A message that sounds like “network access is blocked” can cause an agent to give up on a supported context-mode fetch. A message that sounds like “please use another tool” can cause it to retry an operation that the user explicitly prohibited.

The shared routing layer therefore applies policy before efficiency routing. It normalizes host-specific tool names, checks configured security rules, and only then decides whether a call should pass through, be redirected, modified, or denied. Ordinary Bash, Read, and Grep calls may receive a context-saving nudge. WebFetch and certain high-flood command forms can be redirected. A matching deny pattern takes precedence over those conveniences.

This ordering also explains why routing guidance is not the same as enforcement. A prompt or instruction file can tell an agent that a large result belongs in the sandbox. A hook that can modify or deny a tool call can enforce that choice before the tool runs. A host with neither hook support nor a reliable injection channel may still expose the MCP tools, but it cannot guarantee that the model will follow the routing advice.

Policy checks analyze the command, not just its first word

Context-mode reads user-configured permissions from project-local, project-shared, and adapter-global settings. Within the policy engine, a deny match is more restrictive than an ask or allow match. The server-side path uses the deny portion because an MCP server has no interactive approval dialog of its own; the host hook remains the primary place where allow and ask behavior can be presented to the user.

A naive checker might compare the whole command string with a pattern and stop there. That misses shell composition. echo ok && followed by a denied command is still a denied command. A pipeline can hide a dangerous segment after an innocent producer. A command substitution can execute a nested command while the outer string appears harmless. Context-mode splits chain operators while respecting quotes and then recursively inspects nested subshells. If any segment or nested command matches a deny pattern, the complete call is denied.

The same concern applies when the agent chooses a non-shell language.