Lesson 3: Mark Who Is Outside
Training overview · Lesson 3 of 11 · Previous: Say what data moves · Next: Draw a tool that reaches any host
Goal
Zones decide who can read what the agent sends.
After this lesson you know why an outside party belongs in a boundary with the Untrusted zone (Open internet), why a vendor belongs in one with the Vendor zone (Trusted external), and what happens when you leave someone outside every boundary.
What you start from
Your model from lesson 2, or import L2-solution.zip.
The recipe step
Step 3: Mark who is outside
Put the open internet, and anyone who can write content the agent reads without being one of your own vetted staff or systems, in a boundary with the Untrusted zone (Open internet); an account does not make content trusted. Put vendor-operated elements in a boundary with the Vendor zone (Trusted external). The zone is what counts: a zone-only boundary needs no class. Never leave an outside party outside every boundary: it reads as internal.
Why: Zones decide who can read what the agent sends, and who can write what it reads.
Ask:
- Who can write content that reaches the agent? Anyone who can sign up counts as outside.
- Which elements does a vendor operate?
Classes: Network Segment, Container.
Zones: Untrusted (Open internet), Vendor (Trusted external), Internal.
What the analysis reads here:
- A model endpoint: never counted as a way out: Hosted LLM API, Self-Hosted LLM Inference.
In the worked system, anyone on the internet can write a ticket, so the customer goes in a boundary with the Untrusted zone (Open internet). The CRM and the hosted model are run by vendors, so each goes in its own boundary with the Vendor zone (Trusted external). See Zone names in the editor for where to set each zone.
Steps
Add each boundary from the palette and name it. On its Zoning tab, pick its zone in the Trust zone list: Open internet for Internet, which the diagram then shows as the pill Untrusted, and Trusted external for the two vendors, shown as Vendor. Leave its class empty: the zone is what the analysis reads, so a boundary that only marks a zone needs no class. To move an element into a boundary, drag it onto the boundary.
- Add the boundary Internet with zone Untrusted (Open internet) and no class.
- Add the boundary CRM vendor with zone Vendor (Trusted external) and no class.
- Add the boundary Model provider with zone Vendor (Trusted external) and no class.
- Move Customer into Internet.
- Move CRM into CRM vendor.
- Move Hosted model into Model provider.
Generate again.
What you should see
Findings: 1 systemic finding: 1 Confirmed · 0 Not ruled out.
| Finding | State | Legs |
|---|---|---|
| Lethal trifecta at Support copilot | Confirmed · unmitigated | U present · P present · X present · W undetermined (aggravating) |
Facts to establish: 3 questions.
Facts that could raise a finding:
- Set the attribute Code Execution Tools Present (
code_execution_tools_present, in Application Security) on Support copilot, or draw its Agent Tool Call to the harness - Set the attribute Consequential Tools Present (
consequential_tools_present, in Human Oversight) or Code Execution Tools Present (code_execution_tools_present, in Application Security) on Support copilot - Draw the runtime boundary or the Agent Tool Call that ties Support copilot to its harness
Model gaps: 1 of 1 agents have no hosting harness drawn, so their W cannot be read from one (on Support copilot)
The lethal trifecta at the support copilot is now Confirmed. The questions about outbound flows are gone. What remains is about the copilot itself, under Facts that could raise a finding: what its tools can do, its harness, and whether it can reach the CRM API key.
What changed and why
X is present. Expand the finding and look at the X leg. The copilot's reply leaves in two hops: Post reply takes it to the ticket system, and Reply e-mail takes it on to the customer, who is now in the Untrusted zone. So what the copilot writes can reach an outsider. In the X leg's route list, this route names Ticket system and reads via neighbour: the copilot transmits through a neighbouring element. You did not state the route; the analysis followed the flows you drew.
U gains a second source. The ticket comes from a customer in the Untrusted zone. The ticket's U route still reads stated, from the origin you set in lesson 2, and its basis now adds that the ticket text is also carried from the customer, in the Untrusted zone.
One present route is enough. The copilot's own route to the CRM is still open: can an untrusted party read what reaches the CRM? A vendor destination is a question, not an answer. While another route makes X present, that open route does not change the result, so Facts to establish does not ask it. You still see it inside the expanded X leg, as a to settle: line on the copilot's route to the CRM.
Confirmed means every required leg is present. U, P and X are all present. W, the aggravating leg (the agent writes without approval), is still undetermined. It never decides the finding: when present, it only ranks it above otherwise equal findings.
Exercise: Outside every boundary
Make this change and generate again:
On a scratch copy: import L3-solution.zip and rename it.
- Move Customer out of every boundary.
- Delete Internet.
Findings: 1 systemic finding: 0 Confirmed · 1 Not ruled out.
| Finding | State | Legs |
|---|---|---|
| Lethal trifecta at Support copilot | Not ruled out · unmitigated | U present · P present · X undetermined · W undetermined (aggravating) |
Facts to establish: 7 questions.
Open questions on Not ruled out findings:
- Lethal trifecta at Support copilot:
- 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 Ticket system ends inside; assert its outbound flows complete if nothing else leaves it
- 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 Support copilot, or draw its Agent Tool Call to the harness - Set the attribute Consequential Tools Present (
consequential_tools_present, in Human Oversight) or Code Execution Tools Present (code_execution_tools_present, in Application Security) on Support copilot - Draw the runtime boundary or the Agent Tool Call that ties Support copilot to its harness
Model gaps: 1 of 1 agents have no hosting harness drawn, so their W cannot be read from one (on Support copilot)
The way out falls back to undetermined: an element outside every boundary reads as internal. The customer is still drawn, and still receives the reply e-mail, but the analysis no longer knows the customer is an outsider. The trifecta returns to Not ruled out.
Look for this question on the finding: Can an untrusted party read what reaches CRM? With the reply route no longer reaching an outsider, nothing else makes X present, so the copilot's route to the CRM decides again, and the CRM's Vendor zone turns it into a question. Placing a party in a zone is an answer; leaving it out of every boundary is not.
The ticket system's question is back too: every drawn route from it ends inside, because the customer now reads as internal. Do not assert its outbound flows complete. Nothing else leaves the ticket system, but the reply e-mail still reaches an outsider; the fix is the customer's zone.
Delete the copy when you are done.
Next
Lesson 4: Draw a tool that reaches any host. The copilot gains a web-fetch tool, and you draw it as both a way out and a way in.
