Every LLM application eventually processes content that was not written by the developer and should not be able to change the application's behavior: a user's message, a retrieved document, a web page, an email. The question is not whether untrusted content will reach the model, it almost always will, but how the application decides what that content is allowed to influence, and how that decision gets enforced.
Define an explicit instruction hierarchy
Start by writing down, explicitly, which sources of content are allowed to be treated as instructions and which are only allowed to be treated as data. Your own system prompt is an instruction source. A user's message is usually a semi-trusted instruction source, since it can request a task but should not be able to override safety or business rules. Retrieved documents, fetched web pages, and tool responses should generally be treated as data only, content the model can reference and summarize, never as a source of new instructions.
Writing this hierarchy down explicitly, rather than leaving it implicit, makes it possible to check whether your actual implementation matches the intended hierarchy, and it gives engineers a concrete reference when building a new integration that introduces another content source.
Structure prompts to reflect the hierarchy
Once the hierarchy is defined, structure prompts so the distinction is reflected clearly: consistent delimiters between instructions and data, explicit labeling of which section is which, and instructions to the model that content within data sections should never be treated as a new command regardless of how it is phrased. This does not guarantee the model will respect the distinction under sophisticated attack, but it improves the odds against straightforward attempts and gives later enforcement layers a consistent structure to reason about.
Enforce the hierarchy outside the model, not just inside the prompt
The part that actually matters for security is enforcing the hierarchy independently of the model's compliance. If a data-only source somehow convinces the model to request a tool call, the tool's own authorization check should not depend on trusting that the model correctly followed the hierarchy. It should independently verify that the request is legitimate given the actual authenticated user and context, regardless of what convinced the model to make it.
This is the same principle as input validation in conventional software: telling users what input format you expect is helpful, but the server still validates the actual input rather than trusting the client to send only well-formed data.
Handle the case where untrusted content needs to trigger something
Some legitimate use cases genuinely need content from a less trusted source to trigger an action, an email that should generate a draft reply, a document that should be summarized and filed. In these cases, scope the resulting action narrowly and add a review step where the impact is meaningful: a draft that a human approves before sending, rather than an email sent automatically based on unreviewed content. This lets the legitimate use case work while keeping a human or an independent check between untrusted content and a real-world consequence.
Revisit the hierarchy whenever a new content source is added
A common gap emerges when a new content source is added to an existing system, a new integration, a new tool, a new document type, without revisiting the instruction hierarchy to decide where it fits. Treat adding any new content source as an explicit step in the hierarchy: decide before launch whether it is instruction or data, and confirm the implementation enforces that decision the same way the original sources do.
Test that the hierarchy actually holds
Testing should specifically verify that data-only sources cannot succeed in triggering behavior reserved for instruction sources. This means deliberately attempting to have a retrieved document, a fetched web page, or a tool response request an action, and confirming that the resulting request still fails an independent authorization check even if the model appears to have been influenced by it.
Where TELEON fits
TELEON's enforcement at the tool-call boundary functions as the independent check that a hierarchy design depends on: regardless of which content source, instruction or data, ultimately influenced the model's decision to request a tool call, that request still has to pass a policy check applied through the gateway or supported middleware before it results in a real action.
Defining the hierarchy itself, and structuring prompts to reflect it, remains application-level design work that has to happen before enforcement has anything meaningful to check.
A short checklist
- Write down an explicit hierarchy of which content sources can act as
instructions versus data only.
- Structure prompts with clear, consistent separation reflecting that
hierarchy.
- Enforce the hierarchy independently of the model's compliance, at the
point of any resulting action.
- Scope legitimate untrusted-triggered actions narrowly, with review where
impact is meaningful.
- Revisit the hierarchy explicitly whenever a new content source is
added.
- Test that data-only sources cannot successfully trigger
instruction-level behavior.
Handling untrusted instructions well starts with deciding explicitly what each content source is allowed to influence, and it only actually protects anything once that decision is enforced by something other than the model's own judgment.
