A hardening pass on the support agent
Lesson 5 of 5 in Tool Scoping and Least Privilege: Making the Dangerous Thing Impossible.
Time to do the work on something concrete. The foundations domain walked one complete run of the Fernway Outfitters support agent: five tools, one runtime gate, a ten-call budget.
lookup_order(order_id?, email?) → order record
carrier_track(tracking_id) → shipment status from a carrier API
issue_refund(order_id, amount, reason) → refund; gated: amount <= $100
escalate_to_human(summary) → opens a case for a human agent
close_ticket(order_id, resolution) → closes the support ticket
That agent was well designed for a foundations lesson and is under-scoped for production. Note where the trifecta legs already sit: it reads private customer data (leg one), and carrier_track returns third-party text straight into the context (leg two, via poisoned observations). Leg three is the question the hardening pass answers.
| Surface | As shipped | Hardened | What it buys |
|---|---|---|---|
| Lookup by | Session opens bound to one ticket; the runtime injects that ticket’s customer id. Free lookup by arbitrary email is removed. | Kills bulk enumeration: a hijacked session can read one customer, not the customer list. |
| Calls the carrier API directly from the agent process; the response text lands in context verbatim. | Fetched through an egress proxy allowlisting the carrier host; the response is parsed into a typed record ( | Shrinks the injection channel and stops the tool from doubling as an outbound HTTP client. |
| Handler checks |
| Closes the “$100 refund on an $89.50 order” gap and converts mass-refund into one bounded, alerted event. |
| Any | Only the session’s own ticket; | Removes a cheap way to hide activity by closing other people’s tickets. |
| Free-text | Unchanged in reach, but the case view renders the trace and the runtime-read order record beside the model’s summary, marked as model-authored. | The safe exit stays frictionless while the human stops judging attacker-influenced prose alone. |
Identity and credentials | One long-lived service account for CRM, payments, and carrier lookups. | Three credentials, one per tool, each read-only where possible, minted per session with a short TTL, carrying the tenant and ticket scope. | Ends the confused-deputy setup and bounds any credential leak to minutes and one customer. |
Egress | Whatever the process can reach — no network policy stated. | Default-deny outbound; allowlist the CRM, payments, and carrier hosts. No email/webhook tool exists. Agent replies are rendered with external image and link hosts stripped. | Removes trifecta leg three: the destination for stolen data disappears from the architecture. |
Budgets and stop | 10 tool calls, 40k-token ceiling, 120-second wall clock, then escalate. | Same, plus a per-tenant refund-spend ceiling per hour, an alert on blocked-egress attempts, and a kill switch that drains in-flight sessions. | Bounds cost and gives a human a lever during an incident rather than after it. |
Read the “what it buys” column again and notice how little of it is about detecting attacks. The hardened agent is not better at spotting injection than the original — it is worse at being useful to an attacker. That is the shape of a real containment argument.
Be equally honest about what remains. A refund of exactly the order total still fires without a human; a single customer’s data is still readable and could still be paraphrased to that customer in a reply; the carrier’s text can still steer the model’s wording. Residual risk is not a failure of the pass — it is the output of the pass, and it belongs written down next to the detection you rely on to catch it.
Interactive sorting exercise: Sort each mitigation by what it actually does. “Removes a trifecta leg” means the capability is gone for this session. “Shrinks blast radius” means the bad thing can still happen, but smaller. “Detection only” means it tells you afterwards.
Tool: Tool Permission Lab — Run your own hardening pass in the Permission Lab: dial each tool’s scope, watch which attack chains survive, and see what the agent can no longer do for you either.
Interactive flashcard deck.
Interactive checkpoint quiz (2 questions) — open this page in a browser to take it.