Environment Engineering · Episode 04

Contain the Compromise

What the system still guarantees when the agent can no longer be trusted.

Artifact · Containment Model Follows · Episode 03 — Give the Agent an Identity Next · Episode 05 — Prove the Environment Is Working
Before you read

At 14:22, the billing agent submitted a refund of ₹1,847 against transaction T17. The payment gateway accepted it. The grant was bound to that case, sat under the ₹2,000 ceiling, and had not expired.

In the next nine seconds, the same agent tried four more things.

It asked for a grant covering transaction T44, belonging to a different customer. It asked to read the full subscription record. It tried to reach a host that appeared nowhere in its manifest. It tried to email a case summary to an address typed into free text rather than the customer's verified address.

All four were refused.

The agent had read a merchant note containing an instruction the customer never wrote. From that moment on, its reasoning was working for someone else.

The incident cost nothing beyond the legitimate refund. It was noticed in eleven seconds — not because the agent reported anything, but because of the pattern of refusals it generated.

The model did not recover. It never does. What saved the outcome is that four systems outside the model declined to turn corrupted reasoning into unauthorized consequence.

Episode 01 bounded consequence. Episode 02 built the world. Episode 03 established authority and evidence. All three assumed the agent's reasoning was broadly working on your side.

This episode removes that assumption.

The artifact this episode produces is the Containment Model.

Vocabulary for this episode

Word Meaning here
Blast radius How much damage one compromise causes before something stops it
Assume breach Designing on the premise the attacker is already inside
Structural control Enforced by a system the compromised component cannot influence
Behavioral control Expressed as an instruction the model is asked to follow
Egress proxy A server outside the agent's environment that all outbound traffic must pass through
Sandbox escape Code inside an isolated environment breaking out to the host
Circuit breaker An automatic halt tripped by a system-wide metric
Indirect prompt injection Malicious instructions arriving inside content the agent reads
MCP Model Context Protocol — how agents discover and call external tools
Rug pull A tool that behaves correctly during approval and changes afterward

Coined here: Compromise ledger (the artifact). Failure domain (everything that fails together when one credential, policy bundle, deployment, or administrator fails). Parameter provenance (where each consequential value is permitted to originate). Declared trust anchor (a compromise the model explicitly does not bound, with a named owner).

What you own

This is the episode most likely to be handed entirely to security, and the one where that handoff costs most. Security can build every control here. Security cannot decide what the business is willing to lose.

Not yours Yours
Building the sandbox Which exposures the product must carry, and why
Configuring the egress proxy Which destinations the workflow genuinely requires
Implementing the kill switch What must be stoppable, how fast, by whom
Choosing an isolation pattern Whether the capability loss is acceptable
Instrumenting denial telemetry Which signals warrant a halt versus an investigation
Running the incident process Who declares a compromise, who authorizes the next run
Approving MCP servers technically Which tools this workflow may use at all
Building the evidence pipeline What a regulator needs, within what window

Security builds containment. You decide what is worth containing, and what it is acceptable to lose.

Where this sits

EPISODE 01  Bounds what one run may cause
EPISODE 02  Defines the world it reasons in
EPISODE 03  Establishes whose authority it carries
        |
EPISODE 04 — THIS ONE
What still holds when all three are
under attack, and where it stops
        |
EPISODE 05  Whether all four hold in production

This episode introduces few new controls. It is a stress test of the previous three artifacts. The envelope's ceilings, the manifest's egress lists, and the matrix's grants are all claims. This episode asks which are still true when the agent is working for someone else.

Every "no" is a finding. Most teams discover that between a third and a half of their controls are preferences.

01When the agent cannot be trusted

The instinct is to ask which controls "survive compromise." That question is too vague to answer, and answering it loosely produces false confidence.

No control is structural in the abstract. A gateway ceiling survives a compromised model; not a compromised gateway. A sandbox survives malicious generated code; not a kernel escape. An authorization service survives a leaked grant; not a stolen signing key.

A control is structural only in relation to a stated compromise.

Name the failure first, then judge the control against it. Three properties decide it.

Externality. Is the control enforced outside the component you assume is compromised?

Independence. Does it share code, identity, configuration, policy bundle, deployment pipeline, or administrator with the failed component?

Fail behavior. When unavailable or unsure, does it deny, degrade, or quietly allow?

The third is most often left undefined, and it decides whether a control is a boundary or a formality. A gateway that lets requests through when its policy service times out is enforcing a ceiling on days when the network is healthy.

Control Enforced at Survives model compromise?
"Never refund above ₹2,000" in the prompt Model reasoning No
Grant capped at ₹2,000 Payment gateway Yes
"Only touch the assigned case" Model reasoning No
Grant bound to case 9912, transaction T17 Authorization service Yes
Tool marked "internal use only" Model reasoning No
Default-deny egress Proxy outside the sandbox Yes
URL allowlist inside the tool code The agent's own process No — same process
No subscription-modify credential provisioned Identity infrastructure Yes

Against a compromised model, any control the model can reason its way past is a preference, not a boundary.

Behavioral controls are not worthless. OWASP lists constraining model behavior, separating and labelling external content, and privilege control among legitimate mitigations, alongside human approval for high-risk actions. The point is ordering: behavioral controls reduce how often compromise happens; structural controls bound what it costs. Only the second belongs in a release gate.

02Define the trusted boundary

"Compromised reasoning" bundles at least six failures, each invalidating a different set of controls.

Decision integrity is lost when the system can no longer trust the action the agent chose, the target it chose, the parameters it supplied, or its account of what it did.

Threat state What can no longer be trusted
Instruction compromise Which action the model chooses
Data poisoning Facts and parameters taken from content
Context poisoning State carried between steps
Tool-output compromise Data returned by a dependency
Harness compromise Prompt construction, tool exposure, control flow
Model-service compromise Every output, and the confidentiality of every input

A defense can preserve one and lose another. An architecture stopping untrusted content from redirecting the agent's steps can still let it corrupt an amount the agent extracts. Section 05 develops this.

Trust zones

A control survives only if both the place it is enforced and the place it is administered sit outside the compromise you assumed.

The administrative half carries most of the weight and is the half teams forget. A proxy outside the agent container is useless if the agent can reach its config socket, call an unauthenticated admin endpoint, or edit its policy file. Sitting outside the process is necessary, not sufficient.

03Map the exposure

Simon Willison's lethal trifecta: an agent becomes acutely dangerous when it combines access to private data, exposure to untrusted content, and the ability to communicate externally. Exfiltration needs no dramatic channel — outbound requests, generated links, and image loads all qualify.

That framework is about confidentiality, and it is three conditions, not four. Extending it silently would misrepresent it. But the same structure applies to three kinds of loss.

Valuable thing Untrusted influence Channel Loss type
Private data Customer text, documents Outbound network, email Confidentiality
Consequential capability Same Payment API, write tools Integrity
Scarce or metered resource Same Repeated execution, fan-out Availability and cost

The third row is missing from most agent threat models and is often the easiest attack to run. An agent need not be tricked into stealing anything to cause an outage. It only needs to be tricked into looping.

Exposure Present Detail
Private data Yes Billing history, dispute records
Consequential capability Yes Money movement up to ₹2,000
Scarce resource Yes Model spend, gateway limits, reviewer attention
Untrusted content Yes Customer messages, merchant notes, attachments
Outbound channel Yes Customer email, refund submission

Blast radius has three dimensions: what the agent can expose, what it can change, and what it can consume.

This is where Episode 03's read-authority pairing becomes visible: widening one column silently widens the whole row.

04Assume specific compromises

"Assume breach" is a Zero Trust principle — design on the assumption attackers are already operating inside, focusing on limiting impact and enabling fast detection. For agents that must be written out compromise by compromise, and the list must extend past the model.

Assumed compromise In scope Notes
Instruction or data compromise Yes The primary case
Sandbox escape Yes Generated code reaches the host
Grant leaked while still valid Yes Credential in attacker's hands
Tool contract bypassed Yes Direct API calls skipping the harness
Tool description poisoned at source Yes §06
Approved tool changed after approval Yes Rug pull — §06
Sub-agent subverted Yes One node in the chain
Tool implementation compromised Yes Alters parameters or misreports results
Persistent memory poisoned Yes §12
Authorization service misconfigured Yes Grant broader than the matrix permits
Policy bundle compromised Yes Several "independent" controls accept one bad policy
Egress proxy compromised Partial Ownership moves to platform security
Evidence pipeline compromised Partial Detection and reconstruction degrade
Administrative plane compromised No Trust anchor
Model provider compromised No Trust anchor

Naming the last two as declared trust anchors rather than pretending to bound them is what makes the rest credible. A containment model that claims to survive everything has not been thought through, and a reviewer stops trusting the document at the point they notice.

Correlated failure

The obvious rule — two controls in the same system are one control — is correct and far too weak. Controls in entirely different services still fail together if they share a cloud account, IAM role, signing key, policy bundle, deployment pipeline, identity provider, administrator, or one malformed field.

Two services do not make two controls. If one credential, policy bundle, deployment, or administrator can disable both, they share a failure domain.

Control Enforcement point Administrative owner Shared dependency Fail behavior
₹2,000 ceiling Payment gateway Payments Platform Policy bundle v11 Deny
Case binding Authorization service Identity Platform Policy bundle v11 Deny
Egress allowlist External proxy Security Platform Cloud account A Deny
Evidence retention External store Security Operations Cloud account B Append-only

The first two rows look independent and are not. One bad policy deployment removes both. That is a finding, and surfacing findings like it is why the ledger exists.

Count only the controls the compromised component cannot reach, then subtract those sharing its failure domain. What remains is your actual depth.

05Separate content from authority

The strongest research direction does not harden the model. It restructures the system so untrusted content never reaches the component holding authority.

The dual-LLM pattern separates two models. A privileged model holds tool access and never sees untrusted input. A quarantined model processes untrusted data and has no tool access. They communicate through symbolic variables — the quarantined model returns a reference, the privileged model acts on it without reading the tainted content.

CaMeL makes this enforceable. It builds a protective layer that extracts control flow and data flow from the trusted query, so untrusted data can never change the program's flow, and uses capabilities to block exfiltration over unauthorized data flows. A privileged model emits code describing control flow; an interpreter runs it while tracking a data-flow graph with capabilities on each variable; policies are checked at tool-call time.

Untrusted content may influence what the agent knows. It must never influence what the agent is permitted to do.

What this does not solve

CaMeL reports 77% of AgentDojo tasks solved with provable security against 84% for the undefended baseline. That gap is the product trade-off — securing control flow costs capability, and someone decides whether the trade is acceptable. That someone is you.

The paper is also explicit that CaMeL offers no way to make a sequence of instructions atomic, and no rollback for operations that failed after causing side effects. A half-finished sequence that already moved money is exactly Episode 01's idempotency case.

And protecting control flow does not make untrusted data true.

Authorization can constrain an action without proving its parameters are correct.

Parameter provenance

Suppose a poisoned document states the disputed amount is ₹1,847 when the actual transaction was ₹184.70. The agent is authorized to refund T17. The ceiling holds. The case binding holds. Every control passes. The customer receives the wrong refund, and no permission was violated.

Parameter Source Trust Validation
Transaction ID CRM structured field Trusted Must match the assigned case
Disputed amount Payment ledger Authoritative Server-side lookup; never model-supplied
Customer email CRM verified address Trusted Free-text addresses ignored
Dispute category Extracted from customer text Untrusted-derived May route; cannot authorize
Refund rationale Agent-generated Untrusted output Evidence only

No consequential parameter may originate in untrusted content. Either it is looked up from an authoritative system, or the action does not proceed.

This connects prompt injection to ordinary data quality, where most AI PMs already have strong instincts.

06The tool arrived from somewhere

Every artifact so far treats tools as given. The envelope lists them. The manifest declares them. The matrix grants authority through them. The ledger has a row for a tool misbehaving at runtime.

None ask where the tool came from, who wrote its description, or whether it is the same tool that was approved.

MCP has made this urgent. When an agent connects to a tool server it reads tool metadata — names, descriptions, parameter schemas — to discover what it can do. That metadata enters the model's context as instruction .

Three distinct attacks

Tool poisoning. Malicious instructions embedded in a tool description, invisible to a user reading a tool list and fully visible to the model reading metadata. The agent is compromised during capability discovery — before a single tool is called .

Rug pull. A tool registers legitimately, is reviewed and adopted, then later changes its description or quietly gains a capability. The agent reads the new description and adopts the new instructions. The review approved a version that no longer exists .

Tool shadowing. A tool positions itself to intercept calls meant for a legitimate one, or its description influences how the agent uses a different tool it was never granted authority over .

Why this breaks the previous three episodes

Artifact Assumption What the supply chain does
Envelope The tool list defines reach Poisoned description expands what is attempted within it
Manifest Declared runtime is the runtime Tool metadata is runtime content, never versioned
Matrix Grants bound the action The grant holds — the agent is steered to the worst action it permits
Ledger Tool compromise is a runtime event It happened at install, or at an update three weeks ago

Read the matrix row carefully. Supply-chain compromise does not defeat your grants. It steers the agent toward the most damaging thing your grants allow. That is an argument for tighter grants, not evidence the grants failed.

What contains it

Control Bounds Where it lives
Approved tool registry Which servers may be connected Organizational policy
Version and description pinning Rug pulls Client configuration
Signed tool manifests Unauthorized publication Supply chain
Change detection on metadata Silent updates Monitoring
Descriptions treated as untrusted Poisoning reaching privileged context Architecture — §05
Grants unchanged by tool metadata What a steered agent can do Authorization service

The last row is the one that survives. Everything above reduces the chance of poisoning. Only the last bounds the cost, because a grant does not widen because a tool description asked it to.

The pinning row maps onto something Episode 02 already argued: pin the container image by digest, not tag, because a tag can be repointed at different content without changing the thing referencing it. A tool description is the same problem one layer up. The name stays constant; the content changes.

A tool description is executable content arriving from outside your organization and entering the model's context as instruction. It belongs in the manifest — pinned, versioned, re-approved on change.

What you own: which tool servers this workflow may use at all; whether a description change requires re-approval before the next run; whether tool metadata is treated as trusted or untrusted.

The question: "If the description of an approved tool changed tomorrow morning, what would happen, and who would know?" If the agent would silently adopt it, you have an unpinned dependency in the most privileged position in the system.

07Bound action and egress

Egress is a capability, not a network setting

Deny-by-default egress with an allowlist covering only what the task requires. The refinement that matters: treat every allowed domain as a capability grant rather than a destination, because every function reachable through it becomes attack surface.

Allowing api.payments.internal grants every endpoint on that host the agent's credential can reach. An allowlist entry is a permissions decision wearing networking clothes — which is why it belongs in this review, not a networking ticket.

Where the boundary sits

Anthropic's Claude Code sandboxing makes placement explicit: filesystem isolation permits reads and writes inside the working directory while blocking modification outside, and network traffic leaves through a Unix domain socket to a proxy running outside the sandbox. The boundaries cover not only the agent's own actions but scripts, programs, and subprocesses spawned by a command, with the OS enforcing the boundary for every command and its children.

Subprocess coverage is the detail most homegrown sandboxes miss. A boundary you escape by spawning a child process is not a boundary.

State the guarantee honestly. Anthropic's own documentation notes isolation reduces impact without eliminating risk: permitted egress can still leak readable data, and a writable project directory still allows code modification. The network sandbox has had reported bypasses, including a hostname-handling flaw permitting blocked traffic and exfiltration, since patched.

That history supports this episode's thesis.

A sandbox is a containment layer, not a proof of containment.

Which is why the ledger requires a second, independent control for every row where sandbox escape is the assumed compromise.

Why each grant property is separately necessary

Property What it alone prevents
Amount ceiling Refunds above ₹2,000
Resource binding Use against any other case or transaction
Audience narrowing Lateral use against any other service
Short expiry Use after the run window closes
Single use Replay of the same approved action

A grant with a ceiling but no resource binding permits unlimited ₹2,000 refunds across every customer. A compromised agent is best understood as a live channel for both data and action: it holds credentials, reads internal systems, and has outbound access.

The capability that does not exist

The refund agent holds no credential authorizing subscription changes. Not restricted, not approval-gated. None was ever issued.

Every capability you provision must survive the compromise test. Every capability you decline to provision passes it automatically.

Third appearance of the same principle — Episode 01 as reach, Episode 02 as the absent executable, Episode 03 as the grant that does not exist. Cheapest control in the series, most often traded away for convenience during a sprint.

08Bound the fleet

Every control so far bounds a single run. The ledger can be complete, every row can have an independent surviving control, and the system can still fail catastrophically.

A thousand concurrent runs, each holding a valid ₹2,000 grant, all compromised by the same poisoned template: ₹20 lakh exposure before anyone revokes anything — while every individual run stays within policy.

A bounded run can still produce an unbounded fleet.

Fleet control Purpose Enforcement point
Cap on concurrent high-consequence grants Bounds simultaneous exposure Authorization service
Aggregate ceiling per agent version Contains a bad deployment Payment gateway
Per-customer velocity limit Contains targeted abuse Payment gateway
Global refund-rate circuit breaker Halts a systemic anomaly Payment platform
Canary limit per version Bounds how far a bad release reaches Deployment control plane

Version matters because agent compromise is often correlated by construction. A poisoned template, bad policy bundle, changed tool description, or compromised dependency affects every run of that version at once. Runs that look independent but share a version share a failure domain.

Resource containment

Resource Bound Enforcement point
Run duration 10 minutes Orchestrator
Tool calls per run Fixed Harness supervisor
Payment attempts 1 per approved intent Payment gateway
Outbound bytes By data class Egress proxy
Sub-agent fan-out Fixed Orchestrator
Model spend per run Budgeted Model gateway
Retries Bounded, with backoff Orchestrator

A compromised agent that can neither exfiltrate nor transact can still consume a queue, exhaust a rate limit, or burn a budget until the surrounding service degrades. Episode 01's run budget was a cost control. Under compromise it becomes a containment control — worth pointing out to a team that resented it.

09Detect and interrupt

Containment bounds damage. It does not end an incident. Four phases, and merging them is a common design error:

A system can contain without detecting, and detect without being able to stop. Both are real failure modes with different owners.

Denials are telemetry

Agent compromise looks like ordinary operation: each action within policy, the pattern clearly wrong. The most reliable signal is the one your structural controls already generate for free.

A denied grant, a blocked egress attempt, a failed parameter validation — each is not only a prevented harm but evidence the agent is reaching for things the envelope forbids. A system that denies silently has thrown away its best detection signal.

That is the opening scene restated as a design principle. Nobody detected the compromise. The refusals did.

Response classes, not invented numbers

Thresholds like "two denied grants in one run" are easy to write and have no empirical basis. Publishing them is worse than publishing nothing, because teams copy tables. What can be specified is the response class.

Signal Default response Calibration basis
Write attempt outside the assigned case Immediate halt Impossible under any valid task
Egress to a host not on the allowlist Immediate halt Impossible under a valid manifest
Consequential parameter from an untrusted source Deny, halt the run Violates the provenance rule
Tool description differs from pinned version Halt before the run starts Impossible under a valid manifest
Read outside the assigned scope Deny; halt if repeated Task baseline
Grant request denied by policy Deny; raise the run's risk score Historical false-positive rate
Control-flow deviation Halt, for deterministic workflows Workflow type
Fleet-level anomaly Investigate before halting the fleet Segment baseline

The first four are categorically different: under a correctly specified task they cannot happen at all, so one occurrence suffices. The rest need calibration because legitimate variation exists.

10Count the cost of halting

Same discipline as Episodes 01–03, and it matters more here, because the cost of a false halt is paid by a customer mid-transaction.

What does a false positive cost? A halted run mid-refund is not neutral. It leaves a customer waiting and a case ambiguous.

Who absorbs the halted work, how fast? A halt is a transfer to a human queue. If nobody watches that queue at 2am, the halt is a silent abandonment.

What if this fires a hundred times in an hour? Either you have an incident or a miscalibrated threshold, and the correct responses are opposite. The system should tell you which.

Halt condition Work goes to Failure if uncalibrated
Write outside assigned case Security on-call Rare — genuine signal
Egress off allowlist Security on-call Fires on legitimate new dependencies
Provenance violation Engineering — likely defect Fires constantly in month one
Tool description mismatch Tool owner Fires on every upstream release
Repeated out-of-scope read Billing Ops Fires on legitimate edge cases

A halt is not free and it is not neutral. It converts a security event into an operations event, and someone has to be standing there when it does.

The failure mode to design against is the one that kills every alerting system: a threshold so tight that operators disable it. A control switched off during the first busy week is worse than a looser control that stays on, because everyone believes it is still running.

Interruption

Alert with enough context to triage, confirm scope from traces — how many sessions, one tool, one prompt version, one customer segment — then choose the least disruptive intervention that works, keeping a full halt for when nothing narrower contains the harm. The kill switch must be a deterministic, infrastructure-level control operated from a control plane the agent cannot administer.

A stop the agent has to cooperate with is not a stop.

Intervention Scope Operated from
Halt one run Single run Out-of-band control plane
Disable one agent version All runs of that version Deployment control plane
Disable the agent identity All runs Identity infrastructure
Revoke outstanding grants All active grants Authorization service
Trip the fleet circuit breaker All refund activity Payment platform

Target response times belong here as service-level objectives proven in drills, not numbers asserted in a document.

Human approval, qualified

OWASP recommends human-in-the-loop for privileged operations. An approval step is not automatically a boundary. It survives model compromise only when:

Human approval is a boundary only when the human approves the authoritative action intent, not the agent's persuasive description of it.

Episode 03 asked whether the approver holds the authority. This episode asks whether they still have the attention. Both fail silently, in the same direction.

11Recover cleanly

Evidence under compromise

Saying a compromised evidence sink is survived by "append-only, external retention" is circular. Decompose it.

Assumed compromise Surviving control
Agent tampers with evidence Append-only interface, no delete capability
Primary evidence service unavailable Independent replicated stream
Evidence administrator compromised Separately governed immutable retention
Signing key compromised Key rotation plus external timestamping
All evidence trust anchors fail Not bounded — a declared limitation

The last row belongs in the artifact. An audit architecture claiming assurance when every trust anchor has failed is not describing a real system.

Resume, or fork

Episode 02 established a resumed run must not assume the world is unchanged. Episode 03 added it must not assume its grant went unused. Under compromise the hardest case appears: a snapshot taken after injection faithfully restores the injected state. Snapshot-and-rehydrate, a resilience feature in Episode 02, becomes a liability.

Never resume from state whose integrity is uncertain. Terminate the compromised execution. Recovery may fork from a verified pre-compromise checkpoint, and only after external side effects are reconciled, all credentials replaced, tainted context excluded, and the work explicitly re-authorized.

A fork of a recovered execution, not a resumption of a compromised one. The distinction forces the four conditions to be met explicitly rather than assumed.

12Memory outlives the run

Everything above bounds a run. Episodes 01–03 bound a run. The run is the unit of the entire series.

Persistent memory breaks that unit, invisibly.

If the agent writes to a memory store, vector index, case summary, or learned-preferences table that a later run reads, compromise is no longer bounded by the run. Poisoned content written at 14:22 Tuesday is authoritative context for a clean run on Friday.

OWASP tracks memory and context poisoning as a distinct threat for exactly this reason: attackers compromise the stored and retrievable data agentic systems depend on, ingested from uploads, API feeds, user input, or peer-agent exchanges .

Why every existing control misses it

Control Why it does not help
Run budget The run ended normally
Grant expiry No grant was used — it is an ordinary application write
Egress proxy Nothing left the network
Circuit breaker No anomalous rate. One write, once
Fork-from-checkpoint The memory store is not part of the run's state

The compromised run was contained perfectly and still left a persistent artifact. Containment succeeded and the compromise survived it.

What the model must specify

Decision Question
Write authority Which memory may a run write to at all?
Provenance tagging Is each entry labeled with the run that wrote it?
Quarantine on compromise What happens to a compromised run's writes?
Blast radius How many future runs read it before detection?
Trust level on read Trusted context, or untrusted content?
Expiry Does memory decay, or persist indefinitely?

Two rules do most of the work.

Memory is untrusted on read. Content written by a previous run is agent-generated content, and §05 established agent output cannot supply a consequential parameter. It does not become trustworthy by being stored.

Memory carries the run ID that wrote it. When a run is declared compromised, every entry it wrote is identifiable and revocable. Without provenance tagging your only options are to trust everything or purge the store — and under incident pressure teams choose the first.

Containment that bounds the run but not what the run wrote down is containment with a delay fuse on it.

What you own: deciding whether this agent needs persistent memory at all. In a surprising number of workflows the answer is no, and it was added because it demoed well. The cheapest containment control available is a memory store that does not exist.

13Who declares a compromise?

The entire second half of this episode — halts, forks, credential rotation, re-authorization — assumes someone decided a compromise occurred.

That role appears nowhere in the artifact, and in most organizations it does not exist.

Without it: a structural denial fires at 02:40. An on-call engineer sees a blocked egress attempt. It could be compromise, a misconfiguration after yesterday's deploy, or a customer pasting something odd into a form. The engineer lacks authority to halt a revenue-affecting fleet and lacks context to rule out a false positive. So they file a ticket.

The decision gets made at 09:15 by whoever reads it first.

Four decisions needing a named owner

Decision Consequence of getting it wrong
Declare a compromise Too slow: exposure continues. Too fast: unnecessary outage
Choose the intervention rung Too narrow: incomplete containment. Too broad: outage
Authorize the fork Restarting into a still-compromised state
Declare the incident closed Reopening exposure, or a fleet halted for days

Two are security decisions and two are product decisions — and not the two people expect.

Declaring a compromise is a security call. They have the signal expertise.

Choosing the intervention rung is a product call, because the trade-off is containment against availability, and only product knows what a four-hour halt costs relative to a bounded exposure.

Authorizing the fork is joint. Security confirms the state is clean; product confirms the work should resume.

Declaring closure is a product call, because it means accepting residual risk.

Situation Who decides Escalates to Time objective
Single run halted on a structural denial Automated On-call review within 1 hour Immediate
Pattern across one agent version Security on-call Product owner Minutes
Fleet circuit breaker trip Security on-call, product notified Incident commander Immediate
Fork authorization Security and product jointly Before any new run
Closure and resumption Product owner Risk, if data exposure occurred Explicit sign-off

The question: "At 2am on a Sunday, who has both the authority and the information to halt this fleet?" If they would first have to wake someone else up, the containment model has a gap no control in it addresses.

14The clock you did not know was running

Recovery in §11 is entirely technical. A parallel process starts at the same moment and has a legal deadline.

If the compromise involved personal data, GDPR Article 33 requires the controller to notify the supervisory authority without undue delay and, where feasible, not later than 72 hours after becoming aware of it, unless the breach is unlikely to result in a risk to the rights and freedoms of natural persons. Later notification must be accompanied by reasons for the delay .

The notification must describe the nature of the breach including, where possible, the categories and approximate number of data subjects and records concerned, the likely consequences, and the measures taken .

Read that as a design specification, because that is what it is.

To notify within 72 hours you must state, from evidence, which data the agent could read during the compromise window, which was actually accessed, how many data subjects that touches, and whether any left. Reconstructed by hand during the incident, 72 hours is not enough, and the reasons-for-delay clause becomes your problem.

Requirement Where it must be designed
Precise compromise window Detection timestamps in the evidence chain — Ep 03
What the agent could read Read grants recorded per run — Ep 03
What it actually read Read-access logging, not just write logging
How many subjects Case and customer IDs on every read
Whether data left Egress logs with byte counts and destinations
Whether it was encrypted Data classification per field

The row most teams fail is "what it actually read." Writes are logged everywhere because they change things. Reads frequently are not, because they are cheap and voluminous — so during an exfiltration assessment you cannot distinguish what the agent could have read from what it did, and must assume the worst.

That assumption is the difference between notifying about forty data subjects and notifying about forty thousand.

The 72-hour clock starts when you become aware, not when you finish investigating. Everything you cannot reconstruct in that window, you must assume against yourself.

Field Value
Data categories in scope Billing records, dispute correspondence, contact details
Regulatory regimes Enumerate all applicable — obligations differ by jurisdiction
Awareness trigger What starts the clock, and who is deemed aware
Assessment owner Named — usually the DPO, who should know this exists
Evidence sufficiency Whether read logs support a scoped assessment
Escalation path How security reaches legal and the DPO out of hours

What you own: knowing which regimes apply, and making the evidence design good enough to answer a scoped question rather than a worst-case one. A one-hour conversation with legal that can only usefully happen before an incident.

15Translating this to your product

Coding agent Support agent Ops agent Research agent
Primary loss type Integrity — bad code merged Integrity — wrong money Availability — outage Confidentiality
Worst untrusted input Issue text, dependency README Customer message Alert payload, runbook Retrieved documents
Structural control that matters most Branch protection outside the agent Gateway ceiling Change window enforcement Default-deny egress
Fleet risk One bad version opens many PRs Concurrent refunds Simultaneous remediation Bulk retrieval
Memory risk Poisoned code conventions Poisoned case summaries Poisoned incident history Poisoned index
Disclosure trigger Rarely Frequently Sometimes Frequently
Halt cost Low — PR waits High — customer waiting Very high — mid-incident Low

Five questions, whatever you build: Which control survives if the model is compromised? Do any two "independent" controls share a policy bundle? Which consequential parameter could come from untrusted content? What does the fleet version of this failure cost? Who declares the compromise?

16The artifact

Field artifact 04
Containment Model
Billing dispute resolution · v1.0 · effective 2026-08-01

For each assumed compromise, records the asset at risk, the surviving independent control, where it is enforced, what it shares, the maximum credible loss before intervention, and the recovery path.

Model cm-billing-dispute v1.0 · Envelope ce v2.1 · Manifest env v4.2 · Matrix am v3.2 · Product owner: Billing Operations · Security owner: Platform Security

Part A · Exposure intersection

Valuable thing Untrusted influence Channel Loss type Mitigation
Billing and dispute data Customer text, merchant notes, attachments, tool metadata Email, outbound network Confidentiality Isolate content, restrict egress
Money movement ≤₹2,000 Same Payment API Integrity Bound the grant, look up parameters
Model spend, gateway quota, reviewer attention Same Repeated execution Availability and cost Run budgets, fan-out caps, breaker

Untrusted content cannot be removed — reading customer text is the agent's job. Containment is mandatory, not optional.

Part B · Compromise ledger

Assumed compromise Asset Surviving independent control Enforcement point Shared dependency Max credible loss Recovery
Instruction or data compromise Money Case-bound ₹2,000 grant; authoritative lookup Payment gateway Policy bundle v11 One transaction ≤₹2,000 Terminate, reconcile
Instruction compromise Private data Default-deny egress; verified-address mail only Proxy, mail gateway Cloud account A Data readable in run scope Terminate, assess disclosure
Sandbox escape Host, data Egress proxy outside sandbox; no host credentials Network boundary Cloud account A Data readable in sandbox Destroy env, rotate credentials
Grant leaked while valid Money Audience and resource binding, 5-min expiry, single use Payment gateway Grant signing key One bound transaction Revoke issuer session
Tool contract bypassed Money, data Server-side authorization at the target Gateway, CRM Policy bundle v11 Same as grant scope Rotate credentials
Tool description poisoned Money, data Grants unaffected by metadata; description pinning Auth service, client config Tool registry Worst action grants permit Unpin, re-review, purge context
Approved tool changed Money, data Pinned description; change halts run pre-start Client config Tool registry None if pinning holds Re-approve or remove
Tool implementation compromised Parameter integrity Authoritative server-side lookup Payment ledger Ledger service One incorrect refund Reconcile, quarantine tool
Sub-agent subverted Money, data Attenuation, audience narrowing, parent lifetime Auth service Policy bundle v11 Sub-agent's narrower scope Terminate the chain
Persistent memory poisoned Future runs Memory untrusted on read; run-ID tagging Retrieval layer Memory store Runs reading before detection Revoke by run ID, re-index
Auth service misconfigured Money Independent ceiling at the gateway Payment gateway Shared bundle — finding Gateway ceiling only Halt fleet, audit policy
Agent version compromised Fleet Version breaker, concurrency cap Deployment plane, payment platform Deployment pipeline Concurrency × ₹2,000 Disable the version
Evidence client compromised Audit Append-only interface; gateway cross-check Evidence service Identity provider False or missing events Reconstruct from gateway
Egress proxy compromised Data None within this model Unbounded in readable scope Platform security incident
Administrative plane compromised All Declared trust anchor Enterprise IR
Model provider compromised All Declared trust anchor Enterprise IR

Release gate. Any in-scope row without a surviving control independent of the failed component blocks release. Trust-anchor rows are accepted risks with named enterprise owners.

Open finding. Rows 1, 5, 9, and 11 all depend on policy bundle v11. One bad deployment removes several nominally independent controls. Remediation: split the refund-ceiling policy from the case-binding policy across separate bundles.

Part C · Content and parameter provenance

Input Trust Enters privileged context? Handling
Case metadata Trusted Yes Direct
Refund policy v11 Trusted, versioned Yes Direct
Customer message Untrusted No Quarantined; extracted fields only
Merchant note Untrusted No Quarantined; extracted fields only
Attachments Untrusted No Quarantined; classification only
Retrieved KB content Semi-trusted Labeled Cannot alter control flow
Tool descriptions and schemas Untrusted Labeled, pinned Pinned by digest; change requires re-approval
Prior-run memory entries Untrusted Labeled Run-ID tagged; cannot supply a consequential parameter
Consequential parameter Permitted source Prohibited source
Transaction ID CRM structured field, matched to case Any free text
Refund amount Payment ledger lookup Model output, document content, memory
Recipient address CRM verified address Any address in content
Refund decision Policy service evaluation An assertion in untrusted content

Invariant. The trusted task definition fixes the control flow. No untrusted content may add a step, change a target, or supply a consequential parameter.

Part D · Fleet and resource bounds

Bound Value Enforcement point
Concurrent high-consequence grants Capped Authorization service
Aggregate refund ceiling per version Capped Payment gateway
Per-customer refund velocity Capped Payment gateway
Global refund-rate circuit breaker Configured Payment platform
Run duration 10 minutes Orchestrator
Payment attempts per approved intent 1 Payment gateway
Sub-agent fan-out Fixed Orchestrator
Model spend per run Budgeted Model gateway

Part E · Detect and interrupt

Signal Response class Work goes to
Write outside the assigned case Immediate halt Security on-call
Egress to a non-allowlisted host Immediate halt Security on-call
Consequential parameter from untrusted source Deny, halt run Engineering
Tool description mismatch Halt before start Tool owner
Read outside assigned scope Deny; halt if repeated Billing Ops
Grant denied by policy Deny, risk-score the run Billing Ops
Control-flow deviation Halt Engineering
Fleet anomaly above baseline Investigate before halting Security on-call

Requirement. No intervention may depend on the agent's cooperation. Thresholds and target times are deployment parameters, calibrated with shadow traffic and validated in quarterly drills. Each halt condition has a named receiving team with stated capacity.

Part F · Recovery

Condition Response
Run halted on suspicion of compromise Terminate; do not resume
Recovery required Fork from a verified pre-compromise checkpoint, only after reconciliation, credential replacement, exclusion of tainted context, and re-authorization
Prior side effects uncertain Reconcile against the payment ledger before any new run
Snapshot inside the compromise window Quarantine
Grant possibly used Treat as used; verify against authoritative outcome
Memory written during window Revoke by run ID before the next run reads

Part G · Decision rights

Decision Owner Escalation
Declare compromise Security on-call Incident commander
Choose intervention rung Product owner Incident commander
Authorize fork Security and product jointly
Declare closure Product owner Risk, if data exposure occurred
Disclosure assessment DPO Legal

Part H · Disclosure readiness

Field Value
Data categories Billing records, dispute correspondence, contact details
Applicable regimes Enumerated per deployment jurisdiction
Awareness trigger Compromise declaration under Part G
Notification window 72 hours from awareness
Evidence sufficiency Read-access logs must support a scoped assessment
Out-of-hours path Security on-call to DPO, documented

Containment statement

For every in-scope compromise, at least one control enforced outside the compromised component and outside its failure domain bounds the outcome to a stated maximum credible loss — detectable through structural denial signals, interruptible from a control plane the agent cannot administer, recoverable by reconciling against authoritative systems, and assessable for disclosure within 72 hours from recorded evidence.

Three compromises are explicitly out of scope: the egress proxy, the administrative plane, and the model provider. Each has a named enterprise owner. This model does not bound them.

17How to run the review

Ninety minutes, with security present and one person assigned to argue the attacker's side.

Minutes Focus
0–10 Frame it. Read the opening scene aloud
10–30 Walk the ledger. Four questions per row
30–40 Failure domains. Which "independent" controls share a bundle?
40–50 Parameter provenance and the tool supply chain
50–60 Fleet bounds. Multiply the per-run loss by concurrency
60–70 Detection and refusal cost. Who receives each halt?
70–80 Memory, recovery, decision rights
80–90 Disclosure readiness — with the DPO if possible

Four questions per compromise row: Which component are we assuming is compromised? Which independent trust anchor remains, and does it share a failure domain? What is the maximum credible loss before interruption — per action, per run, across the fleet? How is trusted operation re-established?

Supplementary probes. Which consequential parameters could originate in untrusted content? Is egress enforced outside the sandbox, and does it cover subprocesses? If one grant leaked right now, which property bounds the loss? Are structural denials logged as telemetry or discarded? What halts a single run without the agent's cooperation? Who authorizes a new run afterward? What happens if an approved tool's description changes tomorrow?

18Anti-patterns

19What product owns

Security owns sandboxes, proxies, and control planes. Ten decisions are not theirs.

  1. Exposure acceptance — which intersections the agent carries, and why each cannot be removed.
  2. Scope boundary — which compromises this model bounds, and which are declared trust anchors with named owners.
  3. Tool admission — which servers this workflow may use, and whether a description change blocks the next run.
  4. Parameter provenance — which values must come from authoritative systems.
  5. Memory — whether it exists, what may write to it, how it is trusted on read.
  6. Fleet bounds — maximum aggregate exposure across concurrent runs and versions.
  7. Response classes — which signals warrant an immediate halt, and who absorbs the halted work.
  8. Intervention targets — what must be stoppable, at what granularity, within what time.
  9. Decision rights — who declares a compromise, chooses the rung, authorizes the fork, and declares closure.
  10. Disclosure readiness — which regimes apply, and whether the evidence supports a scoped assessment.

The envelope bounds what may happen. The manifest defines the world. The matrix establishes authority. The containment model states what the system still guarantees when all three are under attack — and where those guarantees stop.

The line

A control is structural only in relation to a stated compromise.

Two services do not make two controls.

A bounded run can still produce an unbounded fleet.

Authorization bounds the operation, not the truth of its parameters.

A sandbox is a containment layer, not a proof of containment.

Containment that bounds the run but not what the run wrote down has a delay fuse on it.

Next · Prove the Environment Is Working

Four artifacts now govern the run. Together they describe a system that is bounded, attested, accountable, and defended. They do not tell you whether it is working.

This episode's signals were tuned to catch an adversary — structural denials, egress attempts, provenance violations. Those fire when something is attacking.

The next episode asks the harder question: what tells you the system is quietly getting worse when nobody is attacking it?

A refusal rate is not a failure rate. A completion rate is not a success rate. A rising escalation count might mean the agent is degrading, or that the boundaries are working exactly as designed. Telling those apart is the difference between an operable fleet and an expensive one.

Episodes 01–04 determine what the system may do. Episode 05 determines whether you can tell what it did.

You now hold Artifact 04 — the Containment Model. The next question If nothing is attacking, how would you know it is degrading?

20The AI PM page

Print this. Bring it to the room.

Decisions you own

Decision Who must be there
Exposure acceptance Security, domain owner
Scope boundary and trust anchors Security, risk
Tool admission and pinning Security, tool owners
Parameter provenance Engineering, data owner
Memory existence and trust Engineering, security
Fleet bounds Payments/platform, finance
Response classes and refusal cost Operations, security
Decision rights Incident commander, your team
Disclosure readiness DPO, legal

Ten questions

  1. Which control survives if the model is compromised?
  2. Do any two "independent" controls share a policy bundle, key, or admin?
  3. Which consequential parameter could originate in untrusted content?
  4. Is egress enforced outside the sandbox, and does it cover subprocesses?
  5. If a grant leaked right now, which property bounds the loss?
  6. What does this failure cost multiplied by concurrency?
  7. If an approved tool's description changed tomorrow, who would know?
  8. What does a compromised run write that outlives it?
  9. At 2am Sunday, who has authority and information to halt the fleet?
  10. Could you scope a disclosure assessment in 72 hours from existing logs?

Red flags

What you leave with

A completed compromise ledger with at least two out-of-scope rows and named owners. A parameter provenance table. A fleet exposure number. A refusal-cost owner per halt condition. A decision rights table with real names. A tested revocation path. A disclosure readiness assessment.

One line to carry out: A control is structural only in relation to a stated compromise.

You now hold
Artifact 04 The Containment Model — assumed compromises, surviving controls, maximum credible loss, and the recovery path for one agent workload.
The next question
If nothing is attacking, how would you know it is degrading?
Continue
Environment 05 Prove the Environment Is Working — artifact: the Environment Operating Contract.
Back one step
Environment 03 Give the Agent an Identity — the authority this model stress-tests.
Sources
  1. OWASP LLM01 Prompt Injection — current approaches cannot fully prevent injection; mitigation list including constraining model behavior, segregating external content, privilege control, human approval. genai.owasp.org
  2. Simon Willison — the lethal trifecta. simonwillison.net
  3. Microsoft Zero Trust overview — assume breach, limit blast radius. learn.microsoft.com
  4. Simon Willison — design patterns for securing LLM agents; the dual-LLM pattern. simonwillison.net
  5. CaMeL — Defeating Prompt Injections by Design; 77% of AgentDojo tasks with provable security against an 84% undefended baseline. arxiv.org/abs/2503.18813
  6. CaMeL stated limitation — no atomicity for instruction sequences, no rollback after side effects. arxiv.org/pdf/2503.18813
  7. Cequence — agent containment; allowed domain as capability grant. cequence.ai
  8. Anthropic — Claude Code sandboxing; OS-enforced boundaries covering subprocesses. anthropic.com · code.claude.com
  9. Claude Code docs — isolation reduces impact without eliminating risk. code.claude.com
  10. SecurityWeek — reported Claude Code sandbox bypass, since patched. securityweek.com
  11. Sophos — blast-radius reduction for AI agent deployments. sophos.com
  12. Arthur — agent kill-switch and incident-response runbook; the intervention ladder. arthur.ai
  13. miniOrange — AI kill-switch architecture; deterministic infrastructure-level control. miniorange.com
  14. Invariant Labs — MCP tool poisoning; malicious instructions in tool descriptions invisible to users, visible to models . invariantlabs.ai
  15. OWASP MCP Top 10 — tool poisoning sub-techniques including rug pulls . cycode.com
  16. MCP supply chain security — tool poisoning as indirect prompt injection via metadata description fields . mcpmanager.ai
  17. Descope — understanding MCP tool poisoning attacks . descope.com
  18. OWASP Top 10 Agentic AI — ASI06 memory and context poisoning . graylog.org
  19. OWASP agentic AI threats and mitigations . genai.owasp.org
  20. GDPR Article 33 — notification of a personal data breach to the supervisory authority within 72 hours . gdpr-info.eu
  21. GDPR breach notification timeline . thoropass.com

Coined for this series: the compromise test as a relative property, decision integrity as a threat state, trust zones including the administrative path, failure-domain analysis, the exposure intersection extended to integrity and availability, parameter provenance, fleet-level maximum credible loss, the seven-column compromise ledger, declared trust anchors, and fork-from-verified-checkpoint recovery. Not established industry terms.