A root is a hint, not a permission
RolesAgent Systems EngineeringCustomer AI Deployment
The question
A filesystem MCP server reads the client's Roots list once and treats any path under a root as authorized for deletion. The client advertises one workspace directory. Two delete requests arrive: one for a sibling directory whose name starts with the workspace name, and one that reaches the parent through an encoded dot-dot segment. What is wrong with this design, and how do you replace it?
Answer it first, aloud or on paper. Then open the answer.
The answer
Show short answer
Roots were informational guidance, never authorization and never a sandbox, and the current revision deprecates them. A string-prefix check accepts both hostile paths, because both begin with the workspace text. Replace the root with an explicit workspaceUri argument or a resource URI, then enforce three layers: authorize the principal for that workspace, normalize the URI and check containment by path components, and run the server under an operating-system sandbox.
Show full answer
What roots were
Earlier revisions let a client advertise Roots and send notifications/roots/list_changed. A root told the server where the user was working. It did not constrain what the server process could read, did not authorize the caller, and created no operating-system boundary. The current revision deprecates roots/list for new designs.
The explicit replacements
| Situation | Replacement |
|---|---|
| scope varies per call | a workspaceUri or directory tool argument |
| the operation already targets a resource | the resource URI |
| one deployment owns one fixed workspace | server configuration |
| code must be unable to escape | a process sandbox or jailed filesystem |
The model can see and repeat an explicit handle. Hidden session scope is harder to inspect, replay, audit and route.
Three layers, every time
- Authorization: may this authenticated principal use this workspace?
- Containment: does the normalized target stay inside the workspace boundary?
- Sandbox: can the operating system stop a compromised server anyway?
Why the prefix check fails
allowed: file:///work/notes
attacker: file:///work/notes-evil/secret.md
traversal: file:///work/notes/%2e%2e/private.mdBoth hostile paths start with the allowed text. Normalize percent-encoded segments first, then compare path components. Re-check containment right before the mutation, because a target can move after the request was validated. A real filesystem server also needs a symbolic-link policy and platform-specific path handling.
The migration adapter
If a peer still needs roots/list during the deprecation window, the server embeds that request in an MRTR input_required result. It never sends a live reverse request. Label the adapter legacy, and never let a legacy root list bypass server authorization.
Follow-ups
L2WorkingWhen is server configuration the right replacement?
Show expected answer
when one deployment owns one fixed workspace; per-call scope belongs in a
workspaceUriargument.L3SeniorWhy re-check containment immediately before the deletion?
Show expected answer
the live record can move outside the workspace between validation and mutation, and a race must not delete the wrong target.
L3SeniorWhy does lexical containment alone not stop a symlink escape?
Show expected answer
a link inside the boundary resolves to a path outside it, so the filesystem layer needs a symlink policy and resolution of the real path.
L4StaffA pinned legacy peer still sends
roots/list. How do you serve it without weakening the modern handler?Show expected answer
an isolated adapter that embeds the request in MRTR input requests, labelled legacy, with authorization and containment still enforced on the server.
Wrong answers
Show the wrong answers that interviewers hear
“The client declared the root, so the server can trust the scope.”
A root is a self-reported hint. Authorization comes from the authenticated principal and server policy.
“Check
startswithon the allowed URI.”A sibling directory and an encoded traversal both pass. Normalize, then compare path components.
“An operating-system sandbox makes the authorization check unnecessary.”
The sandbox is the third layer for a compromised process. It does not decide which principal may touch which workspace.
Taught in
The roots and elicitation lesson states the three-layer rule and shows both hostile paths failing containment.