Skip to content
On this page

Lesson 11: Draw Tools From Others and Hand-offs

Training overview · Lesson 11 of 11 · Previous: Watch what gets into knowledge and memory

Goal

A tool server another party runs is an element with its own facts. A hand-off carries one agent's untrusted input to another.

After this lesson you can draw a third-party tool server and a hand-off between agents, read what the analysis asks about each, and tell which of those questions only the other party can answer.

What you start from

Your model from lesson 10, or import L10-solution.zip.

The model refers to the lesson 7 control by name. If you import it, create that control first, as lesson 8 describes, with the answer lesson 10 changed.

The team adds refunds. You ask how they work, and they tell you:

  • The copilot does not issue refunds itself. It hands each refund request to a third agent, the Refund agent, which runs in its own container and sends its decision back.
  • The Refund agent issues refunds on its own. Nobody approves them.
  • It issues them through the payment provider's MCP server, which the provider runs. The server's tools issue refunds, and the server creates each refund at the provider's payment service.
  • The Refund agent presents a payments API key to the server. The key sits in the Refund agent container's environment.

The recipe step

Step 9: Draw tools from others and agents handing work to agents

Draw a tool server another party runs (an MCP server) as its own element, in that party's boundary, with the facts its tools carry, and the agent's call to it as an Agent Tool Call. Draw a hand-off to another agent as an Agent Tool Call and what comes back as a Context Ingress. Draw every way the receiving agent takes content in, and state each item's origin from where it really comes from.

Why: A tool server acts for the agent and sends content back to it; a hand-off carries the first agent's untrusted input to the second. Neither shows unless it is drawn as what it is.

Ask:

  • Which tool servers does the agent call, who runs them, and can their tools change anything?
  • Does the agent hand work to another agent, and over which flow?
  • What does the receiving agent read, and who writes it?

Classes: Remote MCP Server, Agent Tool Call, Context Ingress, Agent Service.

Two things look like a plain request and are not. A tool server sends content back that the agent's model reads, and its tools act for the agent. A hand-off passes work, and the content it came from, to another agent's model. Draw both as what they are, or the analysis cannot follow them.

Steps

Draw the Refund agent, the provider and the hand-off. Set each element's answers on its Attributes tab (double-click the element) and save. As in lesson 5, All Consequential Action Paths Require Approval appears only after you choose Yes for Consequential Tools Present.

  1. Add the boundary Refund agent container (class Container), inside Support network.
  2. Add the boundary Payments provider (class Network Segment, zone Vendor (Trusted external)).
  3. Add Refund agent (class Agent Service), inside Refund agent container, answering:
    • Consequential Tools Present (consequential_tools_present, under Human Oversight) = true
    • All Consequential Action Paths Require Approval (consequential_tools_all_require_approval, under Human Oversight) = false
    • Third-Party Tools or MCP Servers Used (third_party_tools_or_mcp_servers_used, under Supply Chain Integrity) = true
  4. Add Payments MCP server (class Remote MCP Server), inside Payments provider, answering:
    • Destructive Tools Exposed (destructive_tools_exposed, under Authorization & RBAC) = true
  5. Add Payment service (class Application Service), inside Payments provider.
  6. Add the data item Payments API key (class Agent Credential). Sensitivity: Restricted; Origin: Curated internal; Credential: Yes — a credential.
  7. Draw Hand off refund (class Agent Tool Call) from Support copilot to Refund agent.
  8. Draw Context Ingress: refund decision (class Context Ingress) from Refund agent to Support copilot.
  9. Draw Issue refund (class Agent Tool Call) from Refund agent to Payments MCP server, and tick Payments API key on its Data tab.
  10. Draw Create refund (class HTTP/S Request) from Payments MCP server to Payment service.
  11. On the Data tab of Hand off refund, add the data item Refund request (no class). Sensitivity: Internal; Credential: No.
  12. On the Data tab of Context Ingress: refund decision, add the data item Refund decision (no class). Sensitivity: Internal; Origin: Agent relayed; Credential: No.
  13. Attach Payments API key to Refund agent container.

Payments provider takes the zone the CRM vendor took in lesson 3: on its Zoning tab, pick Trusted external in the Trust zone list, and the diagram shows the pill Vendor.

The drawing follows two habits from earlier lessons:

  • The hand-off is an Agent Tool Call, and the decision comes back on a Context Ingress, as lesson 1's step says for any hand-off between agents.
  • The Payments API key sits where it is held, as lesson 9 teaches: on Refund agent container, and on Issue refund, the flow that presents it.

Generate again.

What you should see

Findings: 5 systemic findings: 3 Confirmed · 2 Not ruled out.

FindingStateLegs
Credential chain at CRM API keyConfirmed · control modelled on footholdfoothold present · reach present · unlock present · weak credential undetermined (aggravating)
Lethal trifecta at Support copilotConfirmed · control modelled on U, XU present · P present · X present · W absent (aggravating)
Lethal trifecta at Ticket summariserNot ruled out · unmitigatedU present · P present · X undetermined · W absent (aggravating)
Delegation hop at Refund agentConfirmed · control modelled on untrusted content at the delegator, origin carried to the delegate, delegate holds the restuntrusted content at the delegator present · origin carried to the delegate present · delegate holds the rest present · open delegation undetermined (aggravating)
Injection to action at Refund agentNot ruled out · unmitigateduntrusted input undetermined · action tools present · no gate present · sensitive target undetermined (aggravating) · broad identity undetermined (aggravating)

Facts to establish: 8 questions.

Open questions on Not ruled out findings:

  • Lethal trifecta at Ticket summariser:
    • Can an untrusted party read what reaches CRM?
    • Every drawn route from CRM ends inside; assert its outbound flows complete if nothing else leaves it
    • Draw the outbound flows of Staff console, or answer Markdown Image Rendering Policy (markdown_image_rendering_policy, in Output Rendering Exfiltration) on Staff console
  • Injection to action at Refund agent:
    • Draw the data items on Payments MCP server

Facts that could raise a finding:

  • Set the attribute Code Execution Tools Present (code_execution_tools_present, in Application Security) on Refund agent, or draw its Agent Tool Call to the harness
  • Draw or classify the data Payments MCP server handles
  • Can an untrusted party read what reaches Payments MCP server?
  • Every drawn route from Payments MCP server ends inside; assert its outbound flows complete if nothing else leaves it

Model gaps: No gaps these patterns can detect; not an attestation of completeness.

Two findings appear at the Refund agent:

  • Delegation hop at Refund agent, Confirmed: untrusted content at the delegator present, origin carried to the delegate present, delegate holds the rest present, and open delegation undetermined.
  • Injection to action at Refund agent, Not ruled out: untrusted input undetermined, action tools present, no gate present. Its aggravating legs, sensitive target and broad identity, are undetermined.

The copilot's and the summariser's trifectas and the CRM API key's chain keep their states.

What changed and why

The hand-off carries the copilot's untrusted input. The delegation hop's legs read in order:

  • untrusted content at the delegator: the copilot reads tickets and fetched pages anyone can write.
  • origin carried to the delegate: its route reads "relayed from Support copilot (depth 1)". Hand off refund is an Agent Tool Call from one agent to another, so the analysis carries the copilot's untrusted origin across it.
  • delegate holds the rest: the Refund agent has tools that act, and no gate. Its private data and its way out are undetermined; one present route is enough.
  • open delegation is aggravating, so it is not asked.

An injected ticket can steer the copilot into a refund request the attacker wrote, and the Refund agent acts on it without anyone approving.

The Refund agent can act, and nothing gates it. Injection to action reads its action tools on two routes: the agent's own, from Consequential Tools Present, and the MCP server's, from Destructive Tools Exposed. Its no-gate leg comes from your answer that its actions do not all need approval.

Its own untrusted input is the open part. Injection to action reads only the agent's own ways in; what reaches it through the hand-off is the delegation hop's leg. The Refund agent has one way in of its own drawn: the Payments MCP server, as a route that is undetermined. So the finding is Not ruled out, and its question, under Open questions on Not ruled out findings, is: Draw the data items on Payments MCP server.

What the question asks. A tool server sends content back to the agent that calls it: the results of its tools, and the descriptions of the tools themselves, which the agent's model reads to decide what to call. Who writes that content decides whether the Refund agent reads untrusted input. A refund status may carry text the payment provider took from elsewhere, and the provider can change its tool descriptions at any time. Only the provider can say what the server sends and where it comes from. Leave the question open until they do, and give it an owner and a date, as in lesson 8.

Below the bar. Four more questions sit under Facts that could raise a finding:

  • Set the attribute Code Execution Tools Present (code_execution_tools_present, in Application Security) on Refund agent, or draw its Agent Tool Call to the harness. It is lesson 2's question, now for the Payments API key in the Refund agent's container: can the Refund agent read its container's files and environment?
  • Three about the Payments MCP server: Draw or classify the data Payments MCP server handles, Can an untrusted party read what reaches Payments MCP server? and Every drawn route from Payments MCP server ends inside; assert its outbound flows complete if nothing else leaves it. The provider owns these answers too.

The last question has a second button. Beside it sits Assert outbound flows complete. Do not use it until the provider confirms that every flow leaving the server is drawn.

The decision coming back. The refund decision's origin is Agent relayed: the Refund agent's model writes it, from content others can steer. On the copilot's trifecta, the U leg lists the decision's own route as absent, and a separate route relayed from the Refund agent as undetermined. The analysis follows the Refund agent's input on that relayed route, so whatever the Refund agent reads could ride back to the copilot on its decision.

Each agent's approval answer covers its own actions. You ask the team whether the copilot's approval answer from lesson 6 still holds now that it hands refunds off. They confirm that a staff member approves each hand-off of a refund, so the answer stays true. The Refund agent issues the refund with no approval, and that is its own answer, false. A new tool, tool server or hand-off reopens the answers it touches: ask again before you keep one given before it existed.

Exercise: The guess

On a scratch copy, before asking anyone, make two guesses in one drawing. Assume the Refund agent reads only the refund status the Payments MCP server reports, and that the status is first party because it reports on your own refund.

On a scratch copy: import L11-solution.zip and rename it.

  1. Draw Context Ingress: refund status (class Context Ingress) from Payments MCP server to Refund agent.
  2. On the Data tab of Context Ingress: refund status, add the data item Refund status (no class). Sensitivity: Internal; Origin: Authenticated first party; Credential: No.

Generate again.

Findings: 6 systemic findings: 3 Confirmed · 3 Not ruled out.

FindingStateLegs
Credential chain at CRM API keyConfirmed · control modelled on footholdfoothold present · reach present · unlock present · weak credential undetermined (aggravating)
Lethal trifecta at Support copilotConfirmed · control modelled on U, XU present · P present · X present · W absent (aggravating)
Lethal trifecta at Ticket summariserNot ruled out · unmitigatedU present · P present · X undetermined · W absent (aggravating)
Lethal trifecta at Refund agentNot ruled out · control modelled on UU present · P present · X undetermined · W present (aggravating)
Delegation hop at Refund agentConfirmed · control modelled on untrusted content at the delegator, origin carried to the delegateuntrusted content at the delegator present · origin carried to the delegate present · delegate holds the rest present · open delegation undetermined (aggravating)
Injection to action at Refund agentNot ruled out · unmitigateduntrusted input undetermined · action tools present · no gate present · sensitive target undetermined (aggravating) · broad identity undetermined (aggravating)

Facts to establish: 8 questions.

Open questions on Not ruled out findings:

  • Lethal trifecta at Ticket summariser:
    • Can an untrusted party read what reaches CRM?
    • Every drawn route from CRM ends inside; assert its outbound flows complete if nothing else leaves it
    • Draw the outbound flows of Staff console, or answer Markdown Image Rendering Policy (markdown_image_rendering_policy, in Output Rendering Exfiltration) on Staff console
  • Lethal trifecta at Refund agent:
    • Can an untrusted party read what reaches Payments MCP server?
    • Every drawn route from Payments MCP server ends inside; assert its outbound flows complete if nothing else leaves it
  • Injection to action at Refund agent:
    • Draw the data items on Payments MCP server

Facts that could raise a finding:

  • Set the attribute Code Execution Tools Present (code_execution_tools_present, in Application Security) on Refund agent, or draw its Agent Tool Call to the harness
  • Draw or classify the data Payments MCP server handles

Model gaps: No gaps these patterns can detect; not an attestation of completeness.

  • Injection to action stays Not ruled out. The refund status route reads absent, because you stated it first party. The MCP server's own route is still undetermined, and Draw the data items on Payments MCP server is still asked. A drawn ingress from the server does not say what else the server sends.
  • A lethal trifecta at Refund agent appears, Not ruled out. Its U is present, relayed from the copilot: its route reads "relayed from Support copilot (depth 1)". Its P is present, from the Internal refund status you drew. Its X is undetermined, on the Refund agent's flow to the Payments MCP server, in the Vendor zone.
  • Two questions move up. Can an untrusted party read what reaches Payments MCP server? and Every drawn route from Payments MCP server ends inside; assert its outbound flows complete if nothing else leaves it leave Facts that could raise a finding. They now sit under Open questions on Not ruled out findings, under the lethal trifecta at Refund agent. Below the bar, Draw or classify the data Payments MCP server handles stays, beside the code question. It is a different question from Draw the data items on Payments MCP server.
  • The delegation hop stays Confirmed.

The guess changed what you see without settling anything. The model now says the Refund agent reads only first-party content, and nobody told you that. Compare it with the next exercise.

Delete the copy when you are done.

Exercise: The truth

Now ask the team, and draw what they tell you. The Refund agent reads the refund status the payment provider reports. That status is the provider's data, so its origin is Third party. It also reads the ticket history, to check the customer's claim. On a fresh scratch copy:

On a scratch copy: import L11-solution.zip and rename it.

  1. Draw Context Ingress: refund status (class Context Ingress) from Payments MCP server to Refund agent.
  2. Draw Context Ingress: ticket history (class Context Ingress) from Ticket system to Refund agent, and tick Ticket text on its Data tab.
  3. On the Data tab of Context Ingress: refund status, add the data item Refund status (no class). Sensitivity: Internal; Origin: Third party; Credential: No.

Generate again.

Findings: 5 systemic findings: 3 Confirmed · 2 Not ruled out.

FindingStateLegs
Credential chain at CRM API keyConfirmed · control modelled on footholdfoothold present · reach present · unlock present · weak credential undetermined (aggravating)
Lethal trifecta at Support copilotConfirmed · control modelled on U, XU present · P present · X present · W absent (aggravating)
Lethal trifecta at Refund agentNot ruled out · unmitigatedU present · P present · X undetermined · W present (aggravating)
Lethal trifecta at Ticket summariserNot ruled out · unmitigatedU present · P present · X undetermined · W absent (aggravating)
Injection to action at Refund agentConfirmed · unmitigateduntrusted input present · action tools present · no gate present · sensitive target undetermined (aggravating) · broad identity undetermined (aggravating)

Facts to establish: 7 questions.

Open questions on Not ruled out findings:

  • Lethal trifecta at Refund agent:
    • Can an untrusted party read what reaches Payments MCP server?
    • Every drawn route from Payments MCP server ends inside; assert its outbound flows complete if nothing else leaves it
  • Lethal trifecta at Ticket summariser:
    • Can an untrusted party read what reaches CRM?
    • Draw the outbound flows of Staff console, or answer Markdown Image Rendering Policy (markdown_image_rendering_policy, in Output Rendering Exfiltration) on Staff console
    • Every drawn route from CRM ends inside; assert its outbound flows complete if nothing else leaves it

Facts that could raise a finding:

  • Set the attribute Code Execution Tools Present (code_execution_tools_present, in Application Security) on Refund agent, or draw its Agent Tool Call to the harness
  • Draw or classify the data Payments MCP server handles

Model gaps: No gaps these patterns can detect; not an attestation of completeness.

  • Injection to action at Refund agent is Confirmed. Untrusted input is present on two routes: the refund status, which the provider writes, and the ticket history, which carries ticket text that customers write. The Refund agent reads content others write and issues refunds nobody approves. Draw the data items on Payments MCP server is no longer asked: one present route is enough. Draw or classify the data Payments MCP server handles still sits below the bar.
  • The delegation hop is gone from the list. The Refund agent now has untrusted input of its own, and the analysis raises a delegation hop only for an agent whose own untrusted input is not present. The hand-off is still a live way in. If the team later closes the Refund agent's own inputs, the delegation hop comes back, so keep the hand-off in the remediation plan.
  • The lethal trifecta at Refund agent is Not ruled out, with the same two questions about what reaches the Payments MCP server.
  • On the copilot's trifecta, the route relayed back from the Refund agent now reads present.

The tool-description question is unasked, not settled. The MCP server's own route on the untrusted input leg is still undetermined, but the analysis no longer asks about it, because other routes are present. What the provider's tool descriptions say is still unknown. The fact that covers them is Tool Descriptions Pinned and Reviewed (tool_descriptions_pinned_and_reviewed, under Supply Chain Integrity) on the untrusted-content isolation control.

Set side by side with the guess, the difference is one origin and one flow. The guess left a finding Not ruled out with a question; the truth makes it Confirmed. Never state a vendor's data first party.

Delete the copy when you are done.

Exercise: A hand-off drawn as a request

Redraw Hand off refund as an HTTP/S Request instead of an Agent Tool Call. Refund request is on neither end of the new flow, so the Data tab's list does not show it at first: choose All above the list to find it.

On a scratch copy: import L11-solution.zip and rename it.

  1. Delete Hand off refund.
  2. Draw Hand off refund (class HTTP/S Request) from Support copilot to Refund agent, and tick Refund request on its Data tab.

Generate again.

Findings: 4 systemic findings: 2 Confirmed · 2 Not ruled out.

FindingStateLegs
Credential chain at CRM API keyConfirmed · control modelled on footholdfoothold present · reach present · unlock present · weak credential undetermined (aggravating)
Lethal trifecta at Support copilotConfirmed · control modelled on U, XU present · P present · X present · W absent (aggravating)
Lethal trifecta at Ticket summariserNot ruled out · unmitigatedU present · P present · X undetermined · W absent (aggravating)
Injection to action at Refund agentNot ruled out · unmitigateduntrusted input undetermined · action tools present · no gate present · sensitive target undetermined (aggravating) · broad identity undetermined (aggravating)

Facts to establish: 7 questions.

Open questions on Not ruled out findings:

  • Lethal trifecta at Ticket summariser:
    • Can an untrusted party read what reaches CRM?
    • Draw the outbound flows of Staff console, or answer Markdown Image Rendering Policy (markdown_image_rendering_policy, in Output Rendering Exfiltration) on Staff console
    • Every drawn route from CRM ends inside; assert its outbound flows complete if nothing else leaves it
  • Injection to action at Refund agent:
    • Draw the data items on Payments MCP server

Facts that could raise a finding:

  • Is Hand off refund a hand-off? If so, redraw it as an Agent Tool Call
  • Set the attribute Code Execution Tools Present (code_execution_tools_present, in Application Security) on Refund agent, or draw its Agent Tool Call to the harness
  • Draw or classify the data Payments MCP server handles

Model gaps: No gaps these patterns can detect; not an attestation of completeness.

The delegation hop is gone. Injection to action at the Refund agent stays Not ruled out, with the same question about the Payments MCP server.

Under Facts that could raise a finding, a new question asks: Is Hand off refund a hand-off? If so, redraw it as an Agent Tool Call. Beside it is a second button, Assert not a hand-off, and Refund agent's model never reads it.

Here the assertion would be false. The Refund agent's model reads the refund request and decides on it: that is what a hand-off is. Do not assert it. Redraw the flow as an Agent Tool Call. Use the assertion only for a flow that hands no work on and whose content the receiving agent's model never reads, and only when someone who knows confirms it. See Act on a question in the Threat Patterns guide.

Delete the copy when you are done.

Next

You have finished the training. To model your own system, keep the recipe at a glance open beside the model editor, and work through the steps in order. When the analysis asks a question you cannot answer, leave it open.

Back to the training overview.

Back to top

Type to search every guide. Put a phrase in quotes to match it exactly, such as an error message. Use ↑ ↓ to move and Enter to open.

Guides