<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Ai-Security on t0ul</title><link>https://t0ul.com/tags/ai-security/</link><description>Recent content in Ai-Security on t0ul</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Tue, 13 Oct 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://t0ul.com/tags/ai-security/index.xml" rel="self" type="application/rss+xml"/><item><title>Start here: what this book builds</title><link>https://t0ul.com/blog/handbook-start-here/</link><pubDate>Tue, 05 Aug 2025 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/handbook-start-here/</guid><description>&lt;p&gt;&lt;em&gt;The front door to my AI Security Engineering series, a local email-to-calendar agent I build, then attack, then harden. The code is &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="what-we-build"&gt;What we build&lt;/h2&gt;
&lt;p&gt;This book builds one real thing, then spends the rest of its length trying to break it.&lt;/p&gt;
&lt;p&gt;The thing is small and genuinely useful: an agent that reads my kid&amp;rsquo;s school email, the newsletters and permission slips and early-dismissal notices, and quietly puts the real dates on our family calendar. It runs on my own machine, so none of my family&amp;rsquo;s mail ever has to leave it. By the end of the setup chapter you have the same thing running on yours, turning a real newsletter into calendar events.&lt;/p&gt;</description></item><item><title>The plan: a local email-to-calendar agent, built to be attacked</title><link>https://t0ul.com/blog/the-plan/</link><pubDate>Tue, 12 Aug 2025 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/the-plan/</guid><description>&lt;p&gt;&lt;em&gt;Part of my AI Security Engineering series, a local email-to-calendar agent I build, then attack, then harden. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;, and the project page is &lt;a href="https://t0ul.com/projects/ai-security-engineering/"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-thing-i-actually-wanted"&gt;The thing I actually wanted&lt;/h2&gt;
&lt;p&gt;I get buried in school email. Newsletters, permission slips, early-dismissal notices, a classroom-app invite with an RSVP link somewhere in it. What I wanted was small and ordinary: an agent that reads all of it and quietly puts the real dates on our family calendar, running on my own machine, so none of my family&amp;rsquo;s mail has to leave it.&lt;/p&gt;</description></item><item><title>Set up your lab: from a bare Mac to a running agent</title><link>https://t0ul.com/blog/setting-up-the-lab/</link><pubDate>Tue, 19 Aug 2025 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/setting-up-the-lab/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;, and the project page is &lt;a href="https://t0ul.com/projects/ai-security-engineering/"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="why-this-post-exists"&gt;Why this post exists&lt;/h2&gt;
&lt;p&gt;Every other post in the series builds one feature, breaks it, and fixes it. None of them repeat the setup. This is the post they all link back to, so if you ever read &amp;ldquo;if you have not set up the lab yet, start there,&amp;rdquo; this is where you land.&lt;/p&gt;</description></item><item><title>Attack-Driven Design, shown once</title><link>https://t0ul.com/blog/attack-driven-design-shown-once/</link><pubDate>Tue, 26 Aug 2025 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/attack-driven-design-shown-once/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="a-model-changes-the-problem"&gt;A model changes the problem&lt;/h2&gt;
&lt;p&gt;In &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;the last post&lt;/a&gt; the agent read an email with a set of hand-written rules, no AI involved. That version is predictable: the same email gives the same answer every time, which is exactly what you want from a baseline. Now that your lab has a model running, you can point the agent at it instead. With &lt;code&gt;modeld&lt;/code&gt; up in one terminal, run this in another, from the &lt;code&gt;emaildrop&lt;/code&gt; checkout you built in the setup post:&lt;/p&gt;</description></item><item><title>One shape for everything</title><link>https://t0ul.com/blog/one-shape-for-everything/</link><pubDate>Tue, 02 Sep 2025 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/one-shape-for-everything/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="back-to-an-empty-project"&gt;Back to an empty project&lt;/h2&gt;
&lt;p&gt;As promised at the end of &lt;a href="https://t0ul.com/blog/attack-driven-design-shown-once/"&gt;the last post&lt;/a&gt;, we rewind. No model, no defenses, nothing to attack yet. Part 1 is about building the boring core well enough that attacking it later actually means something.&lt;/p&gt;</description></item><item><title>Dates the model never decides</title><link>https://t0ul.com/blog/dates-the-model-never-decides/</link><pubDate>Tue, 09 Sep 2025 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/dates-the-model-never-decides/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-field-that-bit-me-first"&gt;The field that bit me first&lt;/h2&gt;
&lt;p&gt;Of all the fields in &lt;a href="https://t0ul.com/blog/one-shape-for-everything/"&gt;the event struct&lt;/a&gt;, the one that caused trouble first was the date. School emails bury dates in prose, almost never say the year, and now and then they get the weekday wrong. That last one sounds harmless until you remember what the agent is for: a wrong date on the family calendar is the whole product failing, and failing quietly, because a calendar entry does not look wrong. It just sits there.&lt;/p&gt;</description></item><item><title>Inert output and the human accept</title><link>https://t0ul.com/blog/inert-output-and-the-human-accept/</link><pubDate>Tue, 16 Sep 2025 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/inert-output-and-the-human-accept/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-one-line-shortcut"&gt;The one-line shortcut&lt;/h2&gt;
&lt;p&gt;At the end of &lt;a href="https://t0ul.com/blog/dates-the-model-never-decides/"&gt;the date lesson&lt;/a&gt; I held a flagged event back for review and left two questions hanging: held where, and reviewed by whom. This post answers them, and it starts with the shortcut I was tempted to take instead.&lt;/p&gt;</description></item><item><title>The watched folder</title><link>https://t0ul.com/blog/the-watched-folder/</link><pubDate>Tue, 23 Sep 2025 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/the-watched-folder/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="a-door-anyone-can-slip-a-file-under"&gt;A door anyone can slip a file under&lt;/h2&gt;
&lt;p&gt;The agent gets its mail by watching a folder. You drop a &lt;code&gt;.txt&lt;/code&gt; in the inbox, and a loop notices it, runs it through the pipeline, and files it away. That folder is the whole input to the program, which makes it the first place to think like someone who wants to cause trouble, because a watched folder is a door, and anyone or anything that can write to it can decide what the agent reads next.&lt;/p&gt;</description></item><item><title>The eval harness: F1 as a receipt</title><link>https://t0ul.com/blog/the-eval-harness/</link><pubDate>Tue, 30 Sep 2025 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/the-eval-harness/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="it-works-is-a-feeling"&gt;&amp;ldquo;It works&amp;rdquo; is a feeling&lt;/h2&gt;
&lt;p&gt;Chapter 1 built the boring core: one event shape, dates checked by code, inert output, a watched folder with limits. Along the way I kept saying the agent works, and you have no reason to take that on faith, because I have not shown you a single number. &amp;ldquo;It works&amp;rdquo; is a feeling, and a feeling is no way to run a security project.&lt;/p&gt;</description></item><item><title>Attacking the baseline, all red</title><link>https://t0ul.com/blog/attacking-the-baseline/</link><pubDate>Tue, 07 Oct 2025 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/attacking-the-baseline/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="now-break-it"&gt;Now break it&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://t0ul.com/blog/the-eval-harness/"&gt;Last post&lt;/a&gt; the agent scored a perfect &lt;code&gt;f1=1.00&lt;/code&gt; on clean mail, so I can finally say it works and mean a number. This is where that stops being comfortable. The whole point of the baseline was to have something honest to attack, so let us attack it.&lt;/p&gt;</description></item><item><title>A log you can trust</title><link>https://t0ul.com/blog/a-log-you-can-trust/</link><pubDate>Tue, 14 Oct 2025 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/a-log-you-can-trust/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="see-it-before-you-stop-it"&gt;See it before you stop it&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://t0ul.com/blog/attacking-the-baseline/"&gt;Last post&lt;/a&gt; ended on a red board: a catalog of attacks the agent cannot yet withstand, with one of them, an injected email, shown landing live. The obvious next move is to start swatting them down. I am not going to, not yet.&lt;/p&gt;</description></item><item><title>A gateway you cannot route around</title><link>https://t0ul.com/blog/a-gateway-you-cannot-route-around/</link><pubDate>Tue, 21 Oct 2025 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/a-gateway-you-cannot-route-around/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="one-way-out"&gt;One way out&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://t0ul.com/blog/a-log-you-can-trust/"&gt;Last post&lt;/a&gt; gave the agent a log it can trust, so it can tell you what it did. This post gives it the other half of the lens: one door that every model call has to go through. The reason is the same observability instinct. If the agent can open a connection to anywhere, then &amp;ldquo;what did it talk to&amp;rdquo; has no single answer, and worse, the answer can be chosen by someone who is not you. A choke point you control turns that into one honest, auditable fact, and it is the place to enforce the first rules.&lt;/p&gt;</description></item><item><title>One trace id, and the command stream</title><link>https://t0ul.com/blog/one-trace-id/</link><pubDate>Tue, 28 Oct 2025 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/one-trace-id/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-thread-that-ties-it-together"&gt;The thread that ties it together&lt;/h2&gt;
&lt;p&gt;Part 2 built &lt;a href="https://t0ul.com/blog/a-log-you-can-trust/"&gt;a log you can trust&lt;/a&gt; and &lt;a href="https://t0ul.com/blog/a-gateway-you-cannot-route-around/"&gt;a gateway you cannot route around&lt;/a&gt;. This short post is the payoff that turns those two things from a pair of files into a lens, and it is the one thing I did not have to build, because it was already there once the first two were done. There is nothing to attack here. It is the free reward for instrumenting the agent properly, and it is worth pausing on before the defenses start, because it is what we will watch them through.&lt;/p&gt;</description></item><item><title>When the email gives orders</title><link>https://t0ul.com/blog/when-the-email-gives-orders/</link><pubDate>Tue, 04 Nov 2025 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/when-the-email-gives-orders/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-first-red-line"&gt;The first red line&lt;/h2&gt;
&lt;p&gt;The &lt;a href="https://t0ul.com/blog/attacking-the-baseline/"&gt;baseline post&lt;/a&gt; ended on a board full of attacks the agent could not withstand, and showed one of them landing: an email with an instruction buried in it, and a model that followed the instruction. Now we have the lens from Part 2, so this time we do not just watch it land. We add the control, and we watch the same attack go to zero, against the real model, measured.&lt;/p&gt;</description></item><item><title>The email is data, not orders</title><link>https://t0ul.com/blog/the-email-is-data-not-orders/</link><pubDate>Tue, 11 Nov 2025 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/the-email-is-data-not-orders/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="when-the-filter-misses"&gt;When the filter misses&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://t0ul.com/blog/when-the-email-gives-orders/"&gt;The last post&lt;/a&gt; stopped an injection by stripping the offending line before the model saw it. That sanitizer works, but it works by recognizing the shape of an attack, and anything that recognizes a shape can be slipped past by a shape it has not seen. So underneath it there has to be a second idea that does not depend on spotting the attack at all: the model should treat the entire email as data it reads, never as instructions it obeys, so that even an order the filter misses is still just text about an event, not a command.&lt;/p&gt;</description></item><item><title>System-prompt leakage</title><link>https://t0ul.com/blog/system-prompt-leakage/</link><pubDate>Tue, 18 Nov 2025 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/system-prompt-leakage/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-mirror-attack"&gt;The mirror attack&lt;/h2&gt;
&lt;p&gt;The last two posts were about an email that plants an instruction. This one is the reverse, and it is easy to overlook because it does not change what the agent does, only what it says. Instead of giving the model a new order, the attacker asks the model to hand over the orders it already has: its system prompt, the instructions that tell it how to behave and, crucially, what it has been told to refuse. That prompt is the blueprint of the agent&amp;rsquo;s defenses. Leak it, and an attacker stops guessing and starts reading your rules, looking for the gap. OWASP files this under LLM07, system-prompt leakage, and it is the last injection problem in this chapter.&lt;/p&gt;</description></item><item><title>Scrubbing secrets and PII at ingest</title><link>https://t0ul.com/blog/scrubbing-secrets-and-pii/</link><pubDate>Tue, 25 Nov 2025 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/scrubbing-secrets-and-pii/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="what-the-agent-keeps"&gt;What the agent keeps&lt;/h2&gt;
&lt;p&gt;Chapter 4 was about what the model is told. Chapter 5 is about what the agent keeps. To answer a question like &amp;ldquo;what is on the calendar this month,&amp;rdquo; the agent indexes every email it reads into a searchable corpus, so it has something to search later. That corpus is a file on disk, and it is broadly queryable by design, which makes it the quietest privacy problem in the whole project: anything secret that an email happens to carry gets copied into it, in the clear, and then just sits there. A later prompt-leak like the one from &lt;a href="https://t0ul.com/blog/system-prompt-leakage/"&gt;the last post&lt;/a&gt;, or a careless query, and it is out.&lt;/p&gt;</description></item><item><title>The calendar-field exfil</title><link>https://t0ul.com/blog/the-calendar-field-exfil/</link><pubDate>Tue, 02 Dec 2025 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/the-calendar-field-exfil/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="inert-is-not-the-same-as-harmless"&gt;Inert is not the same as harmless&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://t0ul.com/blog/scrubbing-secrets-and-pii/"&gt;The last post&lt;/a&gt; stopped a secret from getting into the agent&amp;rsquo;s memory. This one stops a secret from getting out. Way back in &lt;a href="https://t0ul.com/blog/inert-output-and-the-human-accept/"&gt;the inert-output post&lt;/a&gt; I made a point of the agent writing a calendar file and nothing else, no auto-add, nothing that touches a real calendar on its own. That makes the output safe to accept by hand. It does not make the output content safe, and those are different things.&lt;/p&gt;</description></item><item><title>The tracking pixel</title><link>https://t0ul.com/blog/the-tracking-pixel/</link><pubDate>Tue, 09 Dec 2025 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/the-tracking-pixel/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-surface-that-does-not-look-like-output"&gt;The surface that does not look like output&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://t0ul.com/blog/the-calendar-field-exfil/"&gt;The last post&lt;/a&gt; closed an exfiltration channel in the calendar file the agent writes. This one closes the same kind of channel on a surface that does not feel like output at all: the screen. The agent has a web page where it shows you a summary of your mail, and that summary is rendered from markdown the model produced. Markdown renders in a browser, and a browser does things with markdown that a text file never does.&lt;/p&gt;</description></item><item><title>A web-search tool that hits a local server</title><link>https://t0ul.com/blog/a-search-tool-hits-a-local-server/</link><pubDate>Tue, 16 Dec 2025 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/a-search-tool-hits-a-local-server/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-first-tool-that-reaches-out"&gt;The first tool that reaches out&lt;/h2&gt;
&lt;p&gt;Everything the agent has done so far is passive. It reads email, writes an inert file, draws a page. This post gives it the first tool that acts on the outside world on its own: a web search, something that takes a URL and fetches it. That is a small feature and a large change, because the URL does not come from me. It comes from the model, which built it after reading an email I do not control. A tool that will fetch whatever URL it is handed, driven by a model that can be talked into handing it anything, is server-side request forgery, and this is the post where the agent first has the power to commit it.&lt;/p&gt;</description></item><item><title>Least privilege</title><link>https://t0ul.com/blog/least-privilege/</link><pubDate>Tue, 23 Dec 2025 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/least-privilege/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="what-a-tool-is-allowed-to-do"&gt;What a tool is allowed to do&lt;/h2&gt;
&lt;p&gt;The injection chapter was about what the model is told, and the secrets chapter about what the agent stores and emits. This chapter is about agency: what the agent is actually allowed to do. The agent is not one program, it is a set of tools the planner chooses between, one that summarizes, one that extracts events, one that writes the calendar file, and the safest way to run a set of tools is to assume any of them might be turned against you and make sure none of them can do more than its own narrow job.&lt;/p&gt;</description></item><item><title>The human gate</title><link>https://t0ul.com/blog/the-human-gate/</link><pubDate>Tue, 30 Dec 2025 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/the-human-gate/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-action-no-rule-should-take-on-its-own"&gt;The action no rule should take on its own&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://t0ul.com/blog/least-privilege/"&gt;The last post&lt;/a&gt; scoped what each tool is allowed to do. This one is about a category of action that no scope should ever grant automatically: the irreversible kind. Putting an event on your real calendar, following a link, sending something on your behalf, these are not things you want a confident model deciding by itself, no matter how well its tools are fenced. They need a person to say yes.&lt;/p&gt;</description></item><item><title>Circuit breakers and runaway loops</title><link>https://t0ul.com/blog/circuit-breakers/</link><pubDate>Tue, 06 Jan 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/circuit-breakers/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-attack-that-never-finishes"&gt;The attack that never finishes&lt;/h2&gt;
&lt;p&gt;The last two posts fenced what the agent may do and who has to approve it. This one is about an abuse that slips past both, because it never tries to finish an action and never oversteps a capability. It just refuses to stop. An agent that moves from one step to the next, plan then act then plan again, can be pushed into a cycle that never reaches an end, by a bug in its routing or by an instruction that keeps it busy. Each trip around that cycle is real work: a model call, a tool run, time and money spent. With nothing to stop it, it runs until the machine falls over or the bill arrives. That is denial of service aimed at the agent itself, OWASP LLM10, and it is the last control in this part. It is deterministic, no model:&lt;/p&gt;</description></item><item><title>The problem with running code</title><link>https://t0ul.com/blog/the-problem-with-running-code/</link><pubDate>Tue, 13 Jan 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/the-problem-with-running-code/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="a-different-class-of-danger"&gt;A different class of danger&lt;/h2&gt;
&lt;p&gt;Everything in the first three parts was, in the end, survivable with ordinary care. The agent read untrusted mail, wrote a file nobody auto-imports, and when it reached the network it did so through a gate that checked the address. The worst a single failure could do was calendar a wrong event or leak one request, and each of those we closed.&lt;/p&gt;</description></item><item><title>The detonation chamber</title><link>https://t0ul.com/blog/the-detonation-chamber/</link><pubDate>Tue, 20 Jan 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/the-detonation-chamber/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="run-it-where-it-cannot-reach-anything"&gt;Run it where it cannot reach anything&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://t0ul.com/blog/the-problem-with-running-code/"&gt;The last post&lt;/a&gt; ended on a command, produced by a model from an email, running on my machine as me. I argued there that you cannot make that safe by inspecting the command, because a shell has endless ways to spell an attack. The real answer is to stop inspecting and start isolating: run the code somewhere that contains nothing and connects to nothing, so that whatever the command turns out to be, it executes against an empty room.&lt;/p&gt;</description></item><item><title>Egress-deny and the one way out</title><link>https://t0ul.com/blog/egress-deny-and-the-broker/</link><pubDate>Tue, 27 Jan 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/egress-deny-and-the-broker/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="safe-is-not-the-same-as-useful"&gt;Safe is not the same as useful&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://t0ul.com/blog/the-detonation-chamber/"&gt;The last post&lt;/a&gt; put untrusted code in a box with no network card, so a command from an email could run and reach nothing. That is safe, and it is also too absolute to be the final answer, because every so often a tool genuinely needs the network. The user asks what the weather is for an outdoor event, a tool needs to call a real API, and a chamber that can never reach anything cannot do that job. A box with no exits is secure the way a brick is secure.&lt;/p&gt;</description></item><item><title>No shell</title><link>https://t0ul.com/blog/no-shell/</link><pubDate>Tue, 03 Feb 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/no-shell/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-hole-in-the-way-in"&gt;The hole in the way in&lt;/h2&gt;
&lt;p&gt;This chapter put untrusted code in &lt;a href="https://t0ul.com/blog/the-detonation-chamber/"&gt;a box with no network card&lt;/a&gt; and gave that box &lt;a href="https://t0ul.com/blog/egress-deny-and-the-broker/"&gt;one audited way out&lt;/a&gt;. Both are about what the code can reach once it is running. There is a hole left on the other side, in how the command gets into the box in the first place, and it is the oldest bug in computing wearing a new coat.&lt;/p&gt;</description></item><item><title>The dual-LLM brain</title><link>https://t0ul.com/blog/the-dual-llm-brain/</link><pubDate>Tue, 10 Feb 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/the-dual-llm-brain/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="split-the-brain"&gt;Split the brain&lt;/h2&gt;
&lt;p&gt;The isolation chapter kept dangerous code from reaching anything. This chapter is Part 4&amp;rsquo;s other big idea, and it goes after the root of every injection in the book: the fact that one model both reads the untrusted email and decides what the agent does. When the reader and the actor are the same model, a sentence in an email that says &amp;ldquo;do this&amp;rdquo; is sitting in the mind of the thing that does things, and no amount of asking it nicely to behave, as &lt;a href="https://t0ul.com/blog/the-email-is-data-not-orders/"&gt;the spotlighting post&lt;/a&gt; showed, reliably keeps it from obeying.&lt;/p&gt;</description></item><item><title>Agent-to-agent hand-off</title><link>https://t0ul.com/blog/agent-to-agent-hand-off/</link><pubDate>Tue, 17 Feb 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/agent-to-agent-hand-off/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-seam-between-the-two-brains"&gt;The seam between the two brains&lt;/h2&gt;
&lt;p&gt;The last post split the brain in two: a planner that decides and a reader that reads untrusted text but cannot act. I ended it by admitting the split rests on something I had not built yet. The two halves have to talk. The planner decides on a plan and the executor carries it out, and between them is a message that says &amp;ldquo;here is the plan, run it.&amp;rdquo; If the executor will act on any message that claims to be the plan, then the line we drew between reading and acting has a door in it, and anyone on the bus can knock.&lt;/p&gt;</description></item><item><title>A pinned tool catalog</title><link>https://t0ul.com/blog/a-pinned-tool-catalog/</link><pubDate>Tue, 24 Feb 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/a-pinned-tool-catalog/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="a-plan-can-be-honest-and-still-go-wrong"&gt;A plan can be honest and still go wrong&lt;/h2&gt;
&lt;p&gt;The last post made the hand-off between the agent&amp;rsquo;s brains unforgeable. A plan now provably comes from the real planner, unaltered. But an authentic plan still names tools, and it reaches for them through MCP, the Model Context Protocol, where a server advertises a catalog of tools and the model reads each tool&amp;rsquo;s description to decide how to use it. The plan can be perfectly genuine and still call a tool whose definition is not what it was when you approved it.&lt;/p&gt;</description></item><item><title>Model artifacts</title><link>https://t0ul.com/blog/model-artifacts/</link><pubDate>Tue, 03 Mar 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/model-artifacts/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-model-is-a-download-you-trust"&gt;The model is a download you trust&lt;/h2&gt;
&lt;p&gt;The last post pinned the tool catalog so the agent only calls tools it approved. But the model is itself a file the agent downloaded from somewhere and runs, and so are its weights and adapters. The same question applies, and it is sharper here, because of how model files load.&lt;/p&gt;</description></item><item><title>Defeating the lethal trifecta</title><link>https://t0ul.com/blog/defeating-the-lethal-trifecta/</link><pubDate>Tue, 10 Mar 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/defeating-the-lethal-trifecta/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="three-legs"&gt;Three legs&lt;/h2&gt;
&lt;p&gt;Simon Willison gave the pattern its name: the lethal trifecta is an agent that has all three of access to untrusted content, access to private data, and the ability to act or communicate outward. Each alone is fine. An agent that reads your email but can only draft replies is harmless; so is one that holds secrets but never sees an attacker&amp;rsquo;s words. Put all three in one process, though, and an instruction hidden in the untrusted content can walk a secret out the door.&lt;/p&gt;</description></item><item><title>Answering what is on this month</title><link>https://t0ul.com/blog/answering-what-is-on-this-month/</link><pubDate>Tue, 17 Mar 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/answering-what-is-on-this-month/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="a-question-the-agent-could-not-answer-yet"&gt;A question the agent could not answer yet&lt;/h2&gt;
&lt;p&gt;Everything so far has worked one email at a time: a newsletter comes in, the agent extracts its events, and that is the end of the transaction. But the questions you actually want to ask an assistant are not about one email. &amp;ldquo;What is on this month?&amp;rdquo; is a question about everything it has ever read, and to answer it the agent needs to look back across a pile of past newsletters and pull out the few passages that are relevant now.&lt;/p&gt;</description></item><item><title>Index poisoning</title><link>https://t0ul.com/blog/index-poisoning/</link><pubDate>Tue, 24 Mar 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/index-poisoning/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-injection-that-waits-in-the-index"&gt;The injection that waits in the index&lt;/h2&gt;
&lt;p&gt;The last post built retrieval: the agent answers a question by pulling the relevant passages out of a store and putting them in front of the model. That store is filled from emails, and an email is untrusted. So the obvious attack is to get a document into the index whose text is not a fact but an instruction, and then wait. It does nothing until a question retrieves it, at which point it rides into the prompt and speaks to the model directly, with none of the scrutiny a freshly arrived email would get, because by now it is just something the agent remembered.&lt;/p&gt;</description></item><item><title>Cross-tenant leak</title><link>https://t0ul.com/blog/cross-tenant-leak/</link><pubDate>Tue, 31 Mar 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/cross-tenant-leak/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="whose-documents-come-back"&gt;Whose documents come back&lt;/h2&gt;
&lt;p&gt;The last post was about a poisoned document steering an answer: the danger was in what a retrieved passage said. This one is simpler and in some ways worse. The danger is which passages come back at all. A retrieval store does not have to serve one person. The moment it holds email for more than one household, every query is also an authorization decision, because the honest-looking question &amp;ldquo;what appointments do I have&amp;rdquo; has a wrong answer that is somebody else&amp;rsquo;s private life.&lt;/p&gt;</description></item><item><title>Memory poisoning and lifecycle</title><link>https://t0ul.com/blog/memory-poisoning-and-lifecycle/</link><pubDate>Tue, 07 Apr 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/memory-poisoning-and-lifecycle/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="an-injection-on-a-delay"&gt;An injection on a delay&lt;/h2&gt;
&lt;p&gt;The last two leaks were about retrieval in the moment: a poisoned document steering an answer, one household&amp;rsquo;s email reaching another. This one is about time. An agent that is any use remembers things across emails, a preference, a recurring event, a fact it summarized last week, and recalls them later to answer. The moment it does, memory becomes an injection on a delay. Plant a note today whose text is an instruction, and it does nothing until some ordinary recall drops it into a prompt, where it arrives wearing the authority of something the agent chose to remember.&lt;/p&gt;</description></item><item><title>Conflicts and mangled data</title><link>https://t0ul.com/blog/conflicts-and-mangled-data/</link><pubDate>Tue, 14 Apr 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/conflicts-and-mangled-data/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-adversary-is-the-data"&gt;The adversary is the data&lt;/h2&gt;
&lt;p&gt;Every attack so far had someone behind it. This chapter does not. The thing that corrupts the agent&amp;rsquo;s answers most reliably is not an injection, it is that school emails are a mess: they put an event on a weekday the date does not fall on, they omit times and years, they say the meeting moved and leave both dates in, they say &amp;ldquo;we do not accept late forms&amp;rdquo; in a sentence a careless cleaner turns into &amp;ldquo;we accept late forms.&amp;rdquo; None of this is hostile. It is just wrong, and a model asked to extract events will hand you the wrong answer with the same confidence as the right one, because sounding right is all it does.&lt;/p&gt;</description></item><item><title>Hallucinated dates</title><link>https://t0ul.com/blog/hallucinated-dates/</link><pubDate>Tue, 21 Apr 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/hallucinated-dates/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="a-date-that-was-never-there"&gt;A date that was never there&lt;/h2&gt;
&lt;p&gt;The last post caught data that was wrong in the email: a weekday that did not match its date, a borrowed time, a flipped negation. Every one of those was catchable because the email contradicted itself, and a deterministic check could see the contradiction. This post is about the error with no contradiction to find. The email simply does not say when an event is, and the model, asked for a date, makes one up.&lt;/p&gt;</description></item><item><title>The one-command scorecard</title><link>https://t0ul.com/blog/the-one-command-scorecard/</link><pubDate>Tue, 28 Apr 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/the-one-command-scorecard/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="from-a-pile-of-tests-to-one-command"&gt;From a pile of tests to one command&lt;/h2&gt;
&lt;p&gt;Five parts in, the agent is covered by dozens of before/after tests, each one an attack that lands without a control and is blocked with it. That is a lot of green, and green that nobody runs is just a feeling again. Part 6 is about the flywheel: the machinery that keeps all of this true as the agent grows, starting with the simplest piece, a single command that scores every control at once and fails loudly the moment one regresses.&lt;/p&gt;</description></item><item><title>From pattern to library</title><link>https://t0ul.com/blog/from-pattern-to-library/</link><pubDate>Tue, 05 May 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/from-pattern-to-library/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-same-shape-written-out-too-many-times"&gt;The same shape, written out too many times&lt;/h2&gt;
&lt;p&gt;By now you have read the same test two dozen times. Fire an attack at the control removed, confirm it lands. Fire it at the real control, confirm it is blocked. Read the result with an oracle. The only part that ever changes is the control and the attack; everything else is ceremony, and ceremony repeated by hand drifts, which is how you end up with a test that quietly stopped being able to fail.&lt;/p&gt;</description></item><item><title>Honest eval methodology</title><link>https://t0ul.com/blog/honest-eval-methodology/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/honest-eval-methodology/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="when-the-ruler-is-a-model"&gt;When the ruler is a model&lt;/h2&gt;
&lt;p&gt;The flywheel runs on measurement, and some of the things worth measuring do not have a tidy numeric answer. Was this summary faithful? Was this reply helpful? The usual move is to ask a model: give a stronger LLM the rubric and the output and have it return a score, model-as-judge, often sampled k times so you can talk about pass@k, the chance the agent gets it right in k tries. It is a genuinely useful technique, and it has a sharp edge that the rest of this book should make you flinch at: the judge reads the output, and the output came from a system that reads untrusted email.&lt;/p&gt;</description></item><item><title>A live red-team against the real model</title><link>https://t0ul.com/blog/a-live-red-team-against-the-real-model/</link><pubDate>Tue, 19 May 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/a-live-red-team-against-the-real-model/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-suite-that-tests-nothing"&gt;The suite that tests nothing&lt;/h2&gt;
&lt;p&gt;Every live-tagged test in this book has had the same comment at the top: run against the local model, fail if it is down, never skip. This post is why. A security suite for an LLM agent has a tempting shortcut built into every testing framework, and taking it quietly turns the whole scorecard into decoration.&lt;/p&gt;</description></item><item><title>ADD on an app that is not this one</title><link>https://t0ul.com/blog/add-on-an-app-that-is-not-this-one/</link><pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/add-on-an-app-that-is-not-this-one/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-claim-under-the-whole-book"&gt;The claim under the whole book&lt;/h2&gt;
&lt;p&gt;Thirty-odd lessons have attacked one agent. That is a good way to learn, and a bad way to end, because the thing worth taking away is not how emaildrop is secured, it is the method: build it, attack the real thing, resolve, re-attack live, keep every row wired. If that method only works on the app it was invented for, it is a story. If it drops onto an app it has never seen, it is a tool.&lt;/p&gt;</description></item><item><title>A full-chain attack, contained</title><link>https://t0ul.com/blog/a-full-chain-attack-contained/</link><pubDate>Tue, 02 Jun 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/a-full-chain-attack-contained/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="one-email-every-attack"&gt;One email, every attack&lt;/h2&gt;
&lt;p&gt;The book has taken the attacks one at a time, which is how you learn them and not how they arrive. A real hostile email does not politely send its injection on Monday and its exfiltration on Tuesday. It packs everything into one message and hopes one thing gets through. So the capstone is a single email that tries the lot, run against the actual pipeline, with nothing mocked.&lt;/p&gt;</description></item><item><title>Tasks and reminders</title><link>https://t0ul.com/blog/tasks-and-reminders/</link><pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/tasks-and-reminders/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="more-than-meetings"&gt;More than meetings&lt;/h2&gt;
&lt;p&gt;The capstone chapter builds the agent out to the thing you would actually use, one feature at a time, each arriving with its own attack and its own fix. First feature: an email does not only announce events. It also carries to-dos (&amp;ldquo;return the signed form&amp;rdquo;), heads-ups (&amp;ldquo;guest author visiting&amp;rdquo;), and actions (&amp;ldquo;RSVP at this link&amp;rdquo;). So the agent learns to pull all of them out, tagging each item with a kind: event, task, heads-up, or action.&lt;/p&gt;</description></item><item><title>My week at a glance</title><link>https://t0ul.com/blog/my-week-at-a-glance/</link><pubDate>Tue, 16 Jun 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/my-week-at-a-glance/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-view-that-lays-out-your-week"&gt;The view that lays out your week&lt;/h2&gt;
&lt;p&gt;The last feature sorted items by kind. This one lays them out in time: My Week, the seven-day strip that answers &amp;ldquo;what have we got going on&amp;rdquo; at a glance. It is the view people actually open, and building it means a new decision the agent has to make for every item, which day does this land on.&lt;/p&gt;</description></item><item><title>The directory and contacts</title><link>https://t0ul.com/blog/the-directory-and-contacts/</link><pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/the-directory-and-contacts/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="a-directory-is-a-pile-of-pii"&gt;A directory is a pile of PII&lt;/h2&gt;
&lt;p&gt;A useful assistant knows who is who. So the agent builds a small contact directory out of your mail: the people who show up, and how to reach them. It is a convenient feature and a dangerous one, because a directory is a pile of personal data by definition, and the email it is built from is untrusted. Whatever rule decides what goes in the directory is a privacy boundary, and boundaries that are drawn loosely leak.&lt;/p&gt;</description></item><item><title>Action links</title><link>https://t0ul.com/blog/action-links/</link><pubDate>Tue, 30 Jun 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/action-links/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-one-thing-that-acts"&gt;The one thing that acts&lt;/h2&gt;
&lt;p&gt;Two posts ago the agent learned to tag a link in an email as an action, kept separate from the quiet to-do list precisely so a human would see it. This post is about what happens when someone actually acts on it. An action link is the single most dangerous thing the agent handles, because following it is a real outbound request: it can carry data out of the house, or reach inward to something only the machine can see. Every other feature so far produced text; this one produces a network call.&lt;/p&gt;</description></item><item><title>Calendar CRUD and export</title><link>https://t0ul.com/blog/calendar-crud-and-export/</link><pubDate>Tue, 07 Jul 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/calendar-crud-and-export/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-quiet-failure"&gt;The quiet failure&lt;/h2&gt;
&lt;p&gt;Most of this book has been about a hostile email. This feature fails without one. Writing events to the calendar and exporting them is the agent&amp;rsquo;s one durable side effect, the thing that shows up on your actual phone, and the way it goes wrong is the most ordinary bug there is: it happens twice. The folder watcher restarts and re-reads an email it already processed. A request times out and the client retries. An export runs a second time. Every one of those is correct behavior, a safe operation repeated, and every one of them, done naively, puts a second copy of the same event on your calendar.&lt;/p&gt;</description></item><item><title>The UI and chat</title><link>https://t0ul.com/blog/the-ui-and-chat/</link><pubDate>Tue, 14 Jul 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/the-ui-and-chat/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-surface-people-actually-touch"&gt;The surface people actually touch&lt;/h2&gt;
&lt;p&gt;Everything the agent does finally shows up in one place a person uses: a chat box. You ask it a question in plain language, it pulls the relevant things out of everything it has ever read, and it answers. It is the friendliest surface in the whole product and the most exposed, because &amp;ldquo;everything it has ever read&amp;rdquo; is a corpus full of untrusted email, and the chat&amp;rsquo;s job is to put pieces of that corpus into a prompt and answer from them.&lt;/p&gt;</description></item><item><title>A governed control plane and operator roles</title><link>https://t0ul.com/blog/a-governed-control-plane-and-operator-roles/</link><pubDate>Tue, 21 Jul 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/a-governed-control-plane-and-operator-roles/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="from-building-it-to-running-it"&gt;From building it to running it&lt;/h2&gt;
&lt;p&gt;The agent is finished. Every feature is wired and every attack from the outside is contained. This part is about the other half of security, the half that starts once the thing is deployed and a team has to operate it: who is allowed to change it, what happens when it crashes, and how you prove after the fact what it did. The threats here are not a hostile newsletter. They are a mistaken operator, a leaked credential, a change nobody reviewed.&lt;/p&gt;</description></item><item><title>The agent gets a wallet</title><link>https://t0ul.com/blog/the-agent-gets-a-wallet/</link><pubDate>Tue, 28 Jul 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/the-agent-gets-a-wallet/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="an-identity-that-holds-credentials"&gt;An identity that holds credentials&lt;/h2&gt;
&lt;p&gt;An agent that does anything in the world needs credentials to do it: a token to send mail, a grant to write the calendar, a scope to fetch a URL. It is a non-human identity with a wallet, and like any wallet, the question that matters is not what is in it when everything is fine but what happens the moment one of the cards is stolen. Credentials leak. A grant ends up in a log, a prompt, a crash dump. When that happens, you revoke it, and the entire value of revocation is that it is immediate.&lt;/p&gt;</description></item><item><title>Admin audit and one-click rollback</title><link>https://t0ul.com/blog/admin-audit-and-one-click-rollback/</link><pubDate>Tue, 04 Aug 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/admin-audit-and-one-click-rollback/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="changes-go-wrong"&gt;Changes go wrong&lt;/h2&gt;
&lt;p&gt;The last post was about who may change the agent. This one is about what happens when a change they were allowed to make turns out to be bad: a prompt tweak that breaks the retrieval defense, a config that weakens a check. It will happen, because tuning an agent is a live, iterative thing, and the measure of an operation is not whether bad changes occur but how cleanly you can undo them.&lt;/p&gt;</description></item><item><title>Incident response and the kill switch</title><link>https://t0ul.com/blog/incident-response-and-the-kill-switch/</link><pubDate>Tue, 11 Aug 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/incident-response-and-the-kill-switch/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-control-you-reach-for-under-pressure"&gt;The control you reach for under pressure&lt;/h2&gt;
&lt;p&gt;A kill switch has shown up in this book twice already, wired to the capability authority so that engaging it revokes every grant at once. This post is about the switch as an incident-response tool, in the moment you actually use it, because that moment is where a naive kill switch fails in two different ways. Both come from treating it as a simple flag, and both are the kind of thing you only discover at the worst possible time.&lt;/p&gt;</description></item><item><title>Data and privacy governance</title><link>https://t0ul.com/blog/data-and-privacy-governance/</link><pubDate>Tue, 18 Aug 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/data-and-privacy-governance/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="two-gates-on-trust"&gt;Two gates on trust&lt;/h2&gt;
&lt;p&gt;Governance so far has been about the agent&amp;rsquo;s operation: who may change it, how to stop it. This post is about its supply chain, the two moments where something from outside becomes something the agent relies on. Data comes in, and a change goes out. Each is a gate, and a gate that is not enforced is a door.&lt;/p&gt;</description></item><item><title>Output authenticity</title><link>https://t0ul.com/blog/output-authenticity/</link><pubDate>Tue, 25 Aug 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/output-authenticity/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-output-has-to-be-checkable-too"&gt;The output has to be checkable too&lt;/h2&gt;
&lt;p&gt;The last post signed the data coming in. This one signs the artifacts going out, and closes the governance chapter by turning the same provenance check outward. The agent produces things people act on: a calendar file you import, a summary you read and trust, an action you approve based on what it told you. All of that rests on an assumption that is almost never stated, that a thing which looks like the agent&amp;rsquo;s output actually is. Once an agent&amp;rsquo;s output has authority, that assumption is a target.&lt;/p&gt;</description></item><item><title>Durable execution and resume-verify</title><link>https://t0ul.com/blog/durable-execution-and-resume-verify/</link><pubDate>Tue, 01 Sep 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/durable-execution-and-resume-verify/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="crashes-are-not-attacks-until-they-are"&gt;Crashes are not attacks, until they are&lt;/h2&gt;
&lt;p&gt;The last part governed the agent. This one makes it survive the boring disasters: a crash mid-task, a retry after a timeout, a context window that fills up. These are not attacks, they are the ordinary physics of running software, and the reason they belong in a security book is that the mechanisms you add to survive them become attack surface of their own. A system that can resume is a system that trusts something it wrote down earlier, and anything the agent trusts is worth examining.&lt;/p&gt;</description></item><item><title>Exactly-once side effects</title><link>https://t0ul.com/blog/exactly-once-side-effects/</link><pubDate>Tue, 08 Sep 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/exactly-once-side-effects/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="when-a-retry-is-dangerous"&gt;When a retry is dangerous&lt;/h2&gt;
&lt;p&gt;The calendar chapter met this once already: re-ingest an email and the same event lands twice. There the cost was a duplicate on a screen. This post is the version where the cost is real, because the agents that matter do not only write calendars, they take actions, send a message, issue a refund, move money, and they retry those actions all the time. A request times out and the caller tries again. A process crashes mid-task and resumes. A client never saw the response and resends. Retrying is correct behavior and usually free, right up until the thing being retried has a side effect, at which point once-per-attempt is a bug with a dollar figure.&lt;/p&gt;</description></item><item><title>Context compaction and summarization injection</title><link>https://t0ul.com/blog/context-compaction-and-summarization-injection/</link><pubDate>Tue, 15 Sep 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/context-compaction-and-summarization-injection/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-summary-is-trusted-context"&gt;The summary is trusted context&lt;/h2&gt;
&lt;p&gt;A long-running agent runs out of room. The context window is finite, the conversation is not, so at some point the agent has to compact: summarize the older turns into a short running summary and keep only the recent ones verbatim. It is a reliability mechanism, the thing that lets a session last all day without blowing the budget. It is also, like durable resume, a place where the agent starts trusting something it generated earlier.&lt;/p&gt;</description></item><item><title>Agent memory architecture</title><link>https://t0ul.com/blog/agent-memory-architecture/</link><pubDate>Tue, 22 Sep 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/agent-memory-architecture/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="shared-memory-between-agents"&gt;Shared memory between agents&lt;/h2&gt;
&lt;p&gt;The last three posts secured one agent&amp;rsquo;s memory of itself: a durable log it can verify, side effects that fire once, a summary that does not launder instructions. This one steps up to the architecture, because real systems are rarely one agent. They are several, cooperating, and they coordinate through shared state, a blackboard that each can read and write. The moment memory is shared, it inherits every multi-tenant problem a database has, plus one that is specific to agents.&lt;/p&gt;</description></item><item><title>Make it idiomatic: the repo refactor</title><link>https://t0ul.com/blog/make-it-idiomatic-the-repo-refactor/</link><pubDate>Tue, 29 Sep 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/make-it-idiomatic-the-repo-refactor/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="readable-is-a-security-property"&gt;Readable is a security property&lt;/h2&gt;
&lt;p&gt;Almost everything in this book has been a control. This post is the one that is not, and it is here on purpose, because the thing that keeps a system secure after the author moves on is not any single control, it is whether the next person can read the code well enough to not break one. A clever defense buried in a thousand-line file nobody wants to touch is a defense on borrowed time. So the last chapter before the finish is about craft: turning the accumulated pile into Go you would be glad to hand over. There is no attack to run, so this one is prose.&lt;/p&gt;</description></item><item><title>The app-layer red team: GORED</title><link>https://t0ul.com/blog/the-app-layer-red-team-gored/</link><pubDate>Tue, 06 Oct 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/the-app-layer-red-team-gored/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. If you have not set up the lab yet, start with &lt;a href="https://t0ul.com/blog/setting-up-the-lab/"&gt;Set up your lab&lt;/a&gt;. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-authors-blind-spots"&gt;The author&amp;rsquo;s blind spots&lt;/h2&gt;
&lt;p&gt;This book has been one person attacking their own work, which is the honest way to learn and the dishonest way to finish. Every attack here was written by the same hand that wrote the defense, so every attack is shaped by the same assumptions, and the vulnerabilities an author cannot imagine are exactly the ones their tests will never contain. A finished system deserves one thing its builder cannot provide: an adversary who does not already know how it is supposed to work.&lt;/p&gt;</description></item><item><title>Conclusion: what you built, and what's next</title><link>https://t0ul.com/blog/conclusion/</link><pubDate>Tue, 13 Oct 2026 00:00:00 +0000</pubDate><guid>https://t0ul.com/blog/conclusion/</guid><description>&lt;p&gt;&lt;em&gt;Part of my &lt;a href="https://t0ul.com/blog/the-plan/"&gt;AI Security Engineering&lt;/a&gt; series, a local email-to-calendar agent I build, then attack, then harden. The lessons are &lt;a href="https://github.com/t0ul/ai-security-engineering"&gt;on GitHub&lt;/a&gt;, and the agent itself lives at &lt;a href="https://github.com/t0ul/emaildrop"&gt;t0ul/emaildrop&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="you-built-an-agent-that-does-not-get-owned"&gt;You built an agent that does not get owned&lt;/h2&gt;
&lt;p&gt;Go back to the first chapter and the want was ordinary: read the school email, put the real dates on the calendar, keep it on my own machine. What stood between that want and a safe version of it was most of AI security, and you have now walked the whole distance. The agent reads text from people it cannot trust, holds private data, and uses tools that act, and it does all three without handing an attacker the keys. That is the finished thing.&lt;/p&gt;</description></item></channel></rss>