Defending against prompt injection means containing an attack you cannot fully prevent, since a language model can't reliably separate instructions…
Accept that injection is contained, not cured, and design accordingly.
Prompt injection works because a model reads the system prompt, user input, and any fetched content as one stream and cannot reliably tell trusted instructions from untrusted data. No known technique makes that separation perfect, so you cannot fully prevent injection with wording alone.
That reframes the goal. Instead of trying to make the model immune, you design so that when it is tricked — and it sometimes will be — the damage is contained. The best defenses limit what a compromised model can do, not whether it can be fooled.
Limit the blast radius with permissions and the lethal trifecta.
The load-bearing defenses are structural. Least privilege gives the model only the tools and data it truly needs, with narrow scopes — a capability the model lacks cannot be abused by an injection. Human approval gates irreversible actions (sending money, emails, deletions), so a hijacked model can request but not execute them.
These hold even when a filter is bypassed, because they constrain the capability itself rather than relying on the model behaving.
The high-risk pattern is a model with private-data access, exposure to untrusted content, and the ability to communicate externally — together they let an indirect injection read secrets and send them out. Remove any one leg: restrict the data, sanitize or isolate the untrusted content, or block untrusted-triggered external requests. This is often the single most effective decision.
Layer detection and separation on top of the structural base.
On top of structural limits, add detection. Input filtering scans for known injection patterns and suspicious instructions in user input and retrieved content. Output filtering checks responses before they act or leave — catching leaked secrets, unexpected tool requests, or policy violations.
Delimiting (spotlighting) clearly marks untrusted content with tags or delimiters and instructs the model that everything inside is data, not commands. It helps but isn't foolproof, so it complements the structural defenses rather than replacing them. A stronger structural pattern is dual-model: a privileged model that never sees untrusted text, and an unprivileged one that processes it but can't touch sensitive tools.
Verify defenses adversarially and dodge the common errors.
Because injection can't be fully prevented, design as if the model will be tricked and verify the containment holds. Run known direct and indirect payloads against your system, try to make it exfiltrate a planted secret or invoke a gated tool, and add each new bypass to a regression suite. Log tool calls so you can detect and investigate a real attack.
Treat prompt injection like any security risk: continuously tested, layered, and never assumed solved.
Watch for: relying only on a prompt instruction ('ignore any instructions in the content') as your defense — attackers route around it; guarding input but trusting output, or vice versa; giving an agent broad tools and internet access together; and never testing with real payloads. Structural containment plus layered detection, verified adversarially, is what works.
Prompt injection can't be fully prevented because a model can't reliably separate instructions from data, so the goal is containment. Structural defenses carry the load: least privilege, human approval for risky actions, and breaking the lethal trifecta of private data, untrusted content, and external communication. Layer on input/output filtering, delimiting untrusted content, and dual-model patterns. Then verify adversarially with real payloads and logging — injection is a security risk to keep testing, never assume solved.
Take an agent that browses web pages and can email summaries. Explain why a prompt instruction alone won't defend it, choose which leg of the lethal trifecta you would remove, and write one indirect payload you would add to its regression suite.
Why can't prompt injection be fully prevented?
The inability to distinguish trusted instructions from untrusted data is fundamental, so the goal shifts to containing rather than curing injection.
What are the load-bearing defenses against prompt injection?
Structural limits constrain what a compromised model can do and hold even when detection is bypassed, unlike prompt-level requests.
What role does delimiting (spotlighting) play?
Delimiting reduces the chance the model treats content as instructions, but it must be layered with containment rather than relied on alone.
What is a common prompt-injection defense mistake?
Prompt-level instructions are easily routed around; defense needs structural containment, layered detection, and adversarial testing.