{"course":{"slug":"context-engineering","title":"Context Engineering","url":"https://addaly.com/learn/context-engineering","level":"advanced","track":"build"},"lesson":{"slug":"the-lethal-trifecta","title":"Three ingredients, and the recipe only works with all three","url":"https://addaly.com/learn/context-engineering/the-lethal-trifecta","position":71,"of":87,"minutes":8,"answer":"Serious exfiltration requires access to private data, exposure to untrusted content, and some way to send data outwards.","keyIdea":"Serious exfiltration requires access to private data, exposure to untrusted content, and some way to send data outwards, so removing any single one of the three makes the attack fail regardless of how well written the payload is."},"body":{"format":"markdown","text":"## The framing that makes the risk assessable\n\nSimon Willison named this combination the lethal trifecta, and it is the most useful thing to hold in your head when reviewing an agent design, because it turns an open-ended anxiety into a three-item checklist.\n\nAn attacker aiming to steal data through an AI system needs all three of:\n\n1. **Access to private data.** The assistant can read something worth taking: mail, files, database rows, credentials, another customer's records.\n2. **Exposure to untrusted content.** Some path exists by which an attacker's text reaches the window.\n3. **A way to communicate outwards.** Some mechanism by which information can leave, reaching the attacker.\n\nWith all three, the attack is straightforward: the untrusted content instructs the model to read the private data and send it out. With any one missing, it fails.\n\n> Figure: Three legs, and the attack needs all three. Layers, top to bottom: Access to private data (Mail, files, a database, a customer record. Scope it to the one document the user chose); Exposure to untrusted content (Inbound mail, a fetched page, a shared file, a search result. The hardest leg to remove); A way to send data outwards (A rendered image, a link, a fetch tool, even a search query. The most practical leg to remove); Remove any one and it fails (However well the payload is written, and whatever the system prompt says about it). This is a property of the architecture rather than of the prompt, which is what makes it reviewable in an afternoon. It covers exfiltration only, so ask the second question too: what can this system change, and what happens if an attacker picks the change. An injected instruction that deletes a file or quietly biases a summary steals nothing at all.\n\nThe value of the framing is that it is a property of your architecture, not of your prompt. You can review a design against it in an afternoon, and the review yields concrete removals rather than vague resolutions to be careful.\n\n## Applying it\n\nTake a plausible assistant: reads the user's email, can fetch a web page a message links to, can send email on the user's behalf.\n\n- Private data: yes, the mailbox.\n- Untrusted content: yes, anyone can send mail, and any linked page is attacker-controlled.\n- Outward channel: yes, it can send email.\n\nAll three. This design is not securable by prompt engineering, and a warning in the system prompt does not change the assessment. The honest conclusion is that one leg has to go.\n\nNow take a second: a documentation assistant over your public docs, no user data, answers in the UI only.\n\n- Private data: no.\n- Untrusted content: the docs, if anyone outside can edit them.\n- Outward channel: no tools.\n\nOne leg, maybe two. An injected instruction can make it give a wrong or embarrassing answer, a real problem, and a reputational one, but there is nothing to steal and no route out. The appropriate controls are editorial, not architectural.\n\n## Which leg to remove\n\n**Removing private data** is usually cleanest when it is possible. Scope the assistant to a specific document the user selected rather than to their whole drive. Give it the row it needs rather than a query tool over the table. The principle is ordinary least privilege, and in this context it is unusually effective because the model cannot leak what it was never given.\n\n**Removing untrusted content** is the leg people reach for and it is the hardest to hold. It means the assistant cannot follow links, cannot read inbound mail, cannot search the web, cannot ingest user uploads. For most useful products that is most of the product. Where it is achievable is inside a closed corpus with controlled authorship, and you should be sceptical of how controlled it is.\n\n**Removing the outward channel** is the most practical in the largest number of cases, and it is also the one where teams underestimate what counts as a channel. That is the entire subject of the next lesson, and it is more surprising than it sounds.\n\n## The part the framing does not cover\n\nThe trifecta is about exfiltration. Injection can do other harm that the three-item check does not catch.\n\nAn injected instruction can cause **destructive action**: delete files, cancel orders, close tickets, send a message that damages a relationship. No private data needs to leave for that to be serious. A system with untrusted content and any write capability is exposed, whether or not it can read anything sensitive.\n\nIt can also **corrupt the answer**: make a summary omit a clause, make a comparison favour one product, make a code review approve a change. Nothing leaves, nothing is deleted, and the user acts on a wrong output. This is the hardest variant to detect because there is no event to detect.\n\nSo use the trifecta as the first filter and then ask the second question: what can this system change, and what happens if an attacker chooses that change. Together they cover most of the ground.\n\n## Put it in the review\n\nMake the three questions a required section of any design document for a system that calls a model with tools. Four lines: what private data is reachable, what untrusted content can arrive, what can leave, what can be changed.\n\nIt is a low-effort control with an unusually good record, because the failure it catches is not subtle: it is a design that has all three legs and nobody sat down to notice. Teams that ask the question rarely ship that design. Teams that do not, ship it regularly, and find out later."},"check":{"question":"An assistant reads a user's private files and can fetch arbitrary web pages, but has no tool that sends anything outward and renders no remote content. What is the residual exfiltration risk?","options":[{"text":"High, because fetching a page is itself an outbound request that can carry data in the URL.","correct":false,"tempting":"This is the right instinct and usually correct, but it means the design does have an outward channel, so the premise of the question does not hold."},{"text":"None at all, since two of the three legs are absent from the design.","correct":false,"tempting":"Only one leg is absent here; private data and untrusted content are both present, and overcounting removals is how designs get waved through."},{"text":"Low for exfiltration, though injected content can still corrupt the answers the user acts on.","correct":true},{"text":"High, because the model retains the private data between sessions and can emit it once a channel is added later.","correct":false,"tempting":"Models do not retain data across calls; the risk of adding a channel later is real but it is a change-control concern, not retention."}]},"prev":{"slug":"indirect-injection","title":"The attacker is not the one typing","url":"https://addaly.com/learn/context-engineering/indirect-injection"},"next":{"slug":"exfiltration-channels","title":"The outward channels you did not know you had","url":"https://addaly.com/learn/context-engineering/exfiltration-channels"},"authorship":"Founder and series editor: Dr Mustafa Mun. Written by AI models to a written standard. Exam keys checked blind by a second model: 3,665 of 3,666 agreed. Academic review invited.","review":{"status":"Draft, open for academic review"},"cite":"Addaly (2026) 'Three ingredients, and the recipe only works with all three', in Context Engineering. Edited by M. Mun. Addaly. Available at: https://addaly.com/learn/context-engineering/the-lethal-trifecta (Accessed: 13 October 2026).","licence":{"name":"CC BY-NC-SA 4.0","url":"https://creativecommons.org/licenses/by-nc-sa/4.0/"},"reader":{"schema":1,"title":"Three ingredients, and the recipe only works with all three","courseTitle":"Context Engineering","module":{"index":8,"slug":"untrusted-text-and-the-boundary","title":"Untrusted text and the trust boundary"},"answer":null,"keyIdea":"Serious exfiltration requires access to private data, exposure to untrusted content, and some way to send data outwards, so removing any single one of the three makes the attack fail regardless of how well written the payload is.","hero":{"kind":"figure","figure":{"t":"figure","label":"Figure","figure":{"type":"stack","title":"Three legs, and the attack needs all three","layers":[{"label":"Access to private data","detail":"Mail, files, a database, a customer record. Scope it to the one document the user chose"},{"label":"Exposure to untrusted content","detail":"Inbound mail, a fetched page, a shared file, a search result. The hardest leg to remove"},{"label":"A way to send data outwards","detail":"A rendered image, a link, a fetch tool, even a search query. The most practical leg to remove"},{"label":"Remove any one and it fails","detail":"However well the payload is written, and whatever the system prompt says about it"}],"caption":"This is a property of the architecture rather than of the prompt, which is what makes it reviewable in an afternoon. It covers exfiltration only, so ask the second question too: what can this system change, and what happens if an attacker picks the change. An injected instruction that deletes a file or quietly biases a summary steals nothing at all."},"alt":"Figure: Three legs, and the attack needs all three. Layers, top to bottom: Access to private data (Mail, files, a database, a customer record. Scope it to the one document the user chose); Exposure to untrusted content (Inbound mail, a fetched page, a shared file, a search result. The hardest leg to remove); A way to send data outwards (A rendered image, a link, a fetch tool, even a search query. The most practical leg to remove); Remove any one and it fails (However well the payload is written, and whatever the system prompt says about it). This is a property of the architecture rather than of the prompt, which is what makes it reviewable in an afternoon. It covers exfiltration only, so ask the second question too: what can this system change, and what happens if an attacker picks the change. An injected instruction that deletes a file or quietly biases a summary steals nothing at all."}},"blocks":[{"t":"h2","id":"the-framing-that-makes-the-risk-assessable","runs":[{"text":"The framing that makes the risk assessable"}]},{"t":"p","runs":[{"text":"Simon Willison named this combination the lethal trifecta, and it is the most useful thing to hold in your head when reviewing an agent design, because it turns an open-ended anxiety into a three-item checklist."}]},{"t":"p","runs":[{"text":"An attacker aiming to steal data through an AI system needs all three of:"}]},{"t":"ol","start":1,"items":[[{"text":"Access to private data.","b":true},{"text":" The assistant can read something worth taking: mail, files, database rows, credentials, another customer’s records."}],[{"text":"Exposure to untrusted content.","b":true},{"text":" Some path exists by which an attacker’s text reaches the window."}],[{"text":"A way to communicate outwards.","b":true},{"text":" Some mechanism by which information can leave, reaching the attacker."}]]},{"t":"p","runs":[{"text":"With all three, the attack is straightforward: the untrusted content instructs the model to read the private data and send it out. With any one missing, it fails."}]},{"t":"p","runs":[{"text":"The value of the framing is that it is a property of your architecture, not of your prompt. You can review a design against it in an afternoon, and the review yields concrete removals rather than vague resolutions to be careful."}]},{"t":"h2","id":"applying-it","runs":[{"text":"Applying it"}]},{"t":"p","runs":[{"text":"Take a plausible assistant: reads the user’s email, can fetch a web page a message links to, can send email on the user’s behalf."}]},{"t":"ul","items":[[{"text":"Private data: yes, the mailbox."}],[{"text":"Untrusted content: yes, anyone can send mail, and any linked page is attacker-controlled."}],[{"text":"Outward channel: yes, it can send email."}]]},{"t":"p","runs":[{"text":"All three. This design is not securable by prompt engineering, and a warning in the system prompt does not change the assessment. The honest conclusion is that one leg has to go."}]},{"t":"p","runs":[{"text":"Now take a second: a documentation assistant over your public docs, no user data, answers in the UI only."}]},{"t":"ul","items":[[{"text":"Private data: no."}],[{"text":"Untrusted content: the docs, if anyone outside can edit them."}],[{"text":"Outward channel: no tools."}]]},{"t":"p","runs":[{"text":"One leg, maybe two. An injected instruction can make it give a wrong or embarrassing answer, a real problem, and a reputational one, but there is nothing to steal and no route out. The appropriate controls are editorial, not architectural."}]},{"t":"h2","id":"which-leg-to-remove","runs":[{"text":"Which leg to remove"}]},{"t":"p","runs":[{"text":"Removing private data","b":true},{"text":" is usually cleanest when it is possible. Scope the assistant to a specific document the user selected rather than to their whole drive. Give it the row it needs rather than a query tool over the table. The principle is ordinary least privilege, and in this context it is unusually effective because the model cannot leak what it was never given."}]},{"t":"p","runs":[{"text":"Removing untrusted content","b":true},{"text":" is the leg people reach for and it is the hardest to hold. It means the assistant cannot follow links, cannot read inbound mail, cannot search the web, cannot ingest user uploads. For most useful products that is most of the product. Where it is achievable is inside a closed corpus with controlled authorship, and you should be sceptical of how controlled it is."}]},{"t":"p","runs":[{"text":"Removing the outward channel","b":true},{"text":" is the most practical in the largest number of cases, and it is also the one where teams underestimate what counts as a channel. That is the entire subject of the next lesson, and it is more surprising than it sounds."}]},{"t":"h2","id":"the-part-the-framing-does-not-cover","runs":[{"text":"The part the framing does not cover"}]},{"t":"p","runs":[{"text":"The trifecta is about exfiltration. Injection can do other harm that the three-item check does not catch."}]},{"t":"p","runs":[{"text":"An injected instruction can cause "},{"text":"destructive action","b":true},{"text":": delete files, cancel orders, close tickets, send a message that damages a relationship. No private data needs to leave for that to be serious. A system with untrusted content and any write capability is exposed, whether or not it can read anything sensitive."}]},{"t":"p","runs":[{"text":"It can also "},{"text":"corrupt the answer","b":true},{"text":": make a summary omit a clause, make a comparison favour one product, make a code review approve a change. Nothing leaves, nothing is deleted, and the user acts on a wrong output. This is the hardest variant to detect because there is no event to detect."}]},{"t":"p","runs":[{"text":"So use the trifecta as the first filter and then ask the second question: what can this system change, and what happens if an attacker chooses that change. Together they cover most of the ground."}]},{"t":"h2","id":"put-it-in-the-review","runs":[{"text":"Put it in the review"}]},{"t":"p","runs":[{"text":"Make the three questions a required section of any design document for a system that calls a model with tools. Four lines: what private data is reachable, what untrusted content can arrive, what can leave, what can be changed."}]},{"t":"p","runs":[{"text":"It is a low-effort control with an unusually good record, because the failure it catches is not subtle: it is a design that has all three legs and nobody sat down to notice. Teams that ask the question rarely ship that design. Teams that do not, ship it regularly, and find out later."}]}],"check":{"question":[{"text":"An assistant reads a user’s private files and can fetch arbitrary web pages, but has no tool that sends anything outward and renders no remote content. What is the residual exfiltration risk?"}],"options":[{"text":[{"text":"High, because fetching a page is itself an outbound request that can carry data in the URL."}],"correct":false,"tempting":[{"text":"This is the right instinct and usually correct, but it means the design does have an outward channel, so the premise of the question does not hold."}]},{"text":[{"text":"None at all, since two of the three legs are absent from the design."}],"correct":false,"tempting":[{"text":"Only one leg is absent here; private data and untrusted content are both present, and overcounting removals is how designs get waved through."}]},{"text":[{"text":"Low for exfiltration, though injected content can still corrupt the answers the user acts on."}],"correct":true,"tempting":null},{"text":[{"text":"High, because the model retains the private data between sessions and can emit it once a channel is added later."}],"correct":false,"tempting":[{"text":"Models do not retain data across calls; the risk of adding a channel later is real but it is a change-control concern, not retention."}]}],"order":[0,2,1,3],"why":null},"prev":{"slug":"indirect-injection","title":"The attacker is not the one typing","minutes":9},"next":{"slug":"exfiltration-channels","title":"The outward channels you did not know you had","minutes":9}}}