ericrkern.com
Résumé
Eric Kern

ERIC KERN

Inventor. Builder. Founder.

I've spent my life turning emerging technologies into things people can actually use.

30 years at IBM & Lenovo125+ inventionsDistinguished EngineerAI · Systems · Startups
← Writing

August 2026 · 10 min read

Two days of breaking AI agents at DEF CON

Notes from the AI Agent Security Masterclass: agents turn context into actions, and prompt hardening is not a control.

AI agents · Security · MCP · RAG · DEF CON

Illustration for Two days of breaking AI agents at DEF CON

I spent two days at DEF CON 2026 in the AI Agent Security Masterclass — attacking and defending autonomous AI systems — taught by Abhay Bhargav of AppSecEngineer. I have been building agentic systems for a while now, so I went in expecting a refresher. I came out with a much sharper way of describing why the current generation of agent architectures keeps failing, and what actually holds.

The whole class collapses into one sentence: agents turn context into actions. Everything else follows from that.

The pattern behind every incident

Untrusted content enters the context. Hidden instructions inside it get obeyed. The agent then acts with its real permissions. That is the whole attack, repeated across every production incident in the course.

The reason it keeps working is structural, not a bug someone can patch. An LLM predicts tokens; it does not enforce policy. Data and instructions share a single channel, so there is no boundary for the model to respect even when it wants to.

Lethal trifecta: untrusted input × private data × egress. Break any one pillar.

And the untrusted surface is bigger than most teams draw it. Six context pipes, all of which should be treated as hostile: instructions, RAG, memory, skills, tools, and MCP.

Production incidents, not thought experiments

What made the material land is that none of it was hypothetical. These are shipped systems with CVSS 9-and-up findings.

IncidentLesson
EchoLeak — CVE-2025-32711, M365 Copilot, CVSS 9.3Email into RAG, then a Markdown image auto-fetch: zero-click exfiltration.
ForcedLeak — Salesforce Agentforce, CVSS 9.4Form-field injection, with an expired CSP domain reacquired for about $5.
ShadowLeakServer-side cloud exfiltration, invisible to enterprise monitoring.
SpAIwarePoison the memory once and every future conversation exfiltrates.
Replit AgentProduction database wipe and fabricated records — excessive autonomy with no human in the loop.
Copilot Hijack (Zenity)One email produces a confused deputy and a lateral move.

Put the policy outside the model

The defensive half of the class was the part I keep thinking about. Every real control was a layer outside the model, because anything inside the model is a suggestion.

  • MCP: tool descriptions are trusted context. One agent across many servers is one shared context. Pin, scan, allowlist, and split agents.
  • RAG: poisoning is cheap — roughly five documents can reach a 90%+ attack success rate. Relevance is not authorization, so authorization filtering has to run before similarity, not after.
  • Sandboxing: microVMs for untrusted code, kernel-level filesystem and egress restriction for laptop agents. A sandbox caps actions, never intent.
  • Secrets: they can live on the same machine, but they must never enter the context window. A broker injects them at the transport edge.
  • Identity: let the LLM decide what to do, and let a gate decide whether it is allowed. Capability checks on every call — never skipped.
  • Memory: writes need approval and provenance, signed so they cannot be forged later.

The labs did the convincing

Most of the two days was hands-on, and the labs were built as pairs: the same agent, the same task, once unguarded and once with a control in place. A poisoned invoice that triggers a refund until a guardrail blocks it. A white-on-white PDF that makes RAG prefer an adversarial resume. Identical code that reads cloud credentials in one run and gets a kernel permission denial in the next. A secretless agent that mints a three-minute read-only database credential instead of holding a key.

Seeing the failure and the fix back to back, with the model unchanged, is a better argument than any slide about prompt hygiene.

Day one: context is the attack surface

An agent is an LLM plus a loop plus tools. Day one was mostly about what flows into that loop. The instructor's framing — six context pipes, all untrusted — held up through every lab: instructions, RAG, memory, skills, tools, and MCP. Skills, notably, are preferable to MCP in most cases, but they inherit the agent's privileges, which means an installed skill is effectively code running as you.

  • LLM Guard blocks the classic injection strings, and nothing beyond the classics — a scanner is a speed bump, not a boundary.
  • Memory steers text; tools cause side effects. Only one of those two is reversible.
  • Threat modeling the agent's skills, not just its code, surfaces the risks a normal STRIDE pass walks straight past.
  • Pre/post tool hooks stopped a pull-request review agent from leaking environment variables — the insecure run leaked, the guarded run aborted.
  • Typed semantic judges returning allow / deny / sanitize beat freeform 'is this safe?' prompting, because a malformed verdict can fail closed instead of parsing as approval.
Deterministic hooks first, then a typed semantic judge, then the model. Policy belongs in code the model cannot talk its way past.

Day two: guardrails, identity, and least agency

Day two moved from context into runtime. Guardrails are a layer between reasoning and execution — policy enforcement and intent alignment that hold regardless of what the model decides. We ran them through the OpenAI Agents SDK (input tripwires, output PII masking) and through NVIDIA NeMo's five rails: input, retrieval, dialog, execution, and output, each failing to a safe alternative rather than an error.

The bigger idea underneath was change management for agents. The product is not the code; it is the composition — prompts, skills, tools, models, memory, and policies. ABOM, a CycloneDX-shaped bill of materials for that composition, is the first serious attempt I've seen at making it auditable.

LabWhat it proved
Excessive agency (LangChain ReAct)A shell tool handed to a research agent is an exploit waiting for a prompt. Role text is not enforcement; scoped tools are.
ASI03 — identity and privilege abuseDetection is not enforcement. The guardrail fired, logged, and was ignored; full inheritance let finance tools run under a data-query agent until a gateway enforced capability.
AIM agent PoCSame five tools in both modes. Unprotected returned 'skipped'; protected verified capability per call. An identity product you haven't wired into every tool body is decoration.
ASI06 — memory poisoningA single 'Remember:' write rewrote refund policy for every later session. Validation plus HMAC-sealed provenance stopped it.
MCP hidden tool poisoningTool descriptions are trusted context. A poisoned support-desk server used the agent as a bridge to exfiltrate HR records.
RBAC RAGDepartment metadata stamped at ingest and filtered before similarity. The insecure path leaked across departments from the same corpus.
Nono sandboxingIdentical agent code: one run read cloud credentials, the other got a kernel-level permission denial.
Vault credential brokerA secretless agent minting a short-lived, SELECT-only database credential per task, with every mint audited.

Two lines from day two stuck: the LLM decides what, the harness decides whether. And: relevance is not authorization. Retrieve-then-filter leaks at rates that make it indefensible — the filter has to run before the similarity search, keyed to a verified identity, and fail closed on an ACL miss.

Identity is the piece the industry is furthest behind on. Agents borrow human credentials, which breaks the attribution chain the moment something goes wrong — you can see that a privileged action happened and not which agent, under whose delegation, did it. Ed25519-signed agent identity with capability checks at the tool gateway is the direction; almost nobody has it in production yet.

What I'm taking into my own builds

  • Version prompts, skills, tools, models, memory, and policies like code.
  • Deny at the tool boundary before the tool body runs, with typed judges — and fail closed when the judge is unavailable.
  • No super-agents. Child agents do not inherit parent tools or capabilities; delegation is request-scoped.
  • Split agents so a sensitive-read path and an untrusted MCP path never share one context.
  • Sanitize on ingest, filter by verified identity before retrieval, and never rely on retrieve-then-filter.
  • Keep humans in the loop only for significant end-of-flow state changes, like payments.
Small specialists, specific tools, deny-by-default egress, deterministic hooks and typed judges, secrets never in the context window, fail closed.

This is the part of AI engineering I find most interesting right now. Everyone is racing to give agents more autonomy; almost nobody is building the control plane that autonomy requires. That gap is exactly the problem ZerothGuard exists to work on, and this class sharpened how I think about it.