AI security · September 9, 2026
AI Guardrails That Hold: Architecture Over Prompts
You cannot instruct a model into being safe, because instructions and data are the same tokens. The controls that survive contact with an attacker sit outside the model entirely.
By Shihab Shahriar Antor · Updated 2026-09-09
The usual first attempt at securing an agent is a paragraph in the system prompt telling the model to ignore instructions found in documents. It helps a little and it is not a control. The model is a single sequence predictor over one context window, and your paragraph and the attacker's paragraph are competing on equal terms inside it.
That is not a bug to be patched. It follows from how the architecture works, so the defences have to live somewhere the model cannot be talked out of.
Direct and indirect injection are different problems
Direct injection is a user typing something adversarial into your chat box. It is the version everyone tests for, and it is mostly a content-policy problem, because the user is attacking a session they already own.
Indirect injection is instructions arriving inside content the model retrieves: a web page, a document in the knowledge base, a code comment, an email, a calendar invite, text painted into an image. Here the attacker is not the user. They are attacking your user through your agent, and the agent runs with your user's permissions. This is the one that matters and it is much less tested.
Controls that work, in order of how much they buy
These are ordered deliberately. The first two do most of the work and the last two are refinements, which is the reverse of the order teams usually implement them.
| Control | Enforced where | What it stops |
|---|---|---|
| Permissions resolved outside the model | The tool boundary, from the session identity, before the tool runs | Everything that depends on the model being persuaded to exceed its authority. If the model literally cannot reach a record the user cannot reach, no prompt makes it do so. This is the single highest-value control and it is ordinary authorisation engineering. |
| Confirmation for irreversible actions | The application, showing the concrete action to a human | Silent destructive operations. Sending, deleting, paying, publishing, granting access. The check must display exactly what will happen, since a confirmation dialogue the model wrote is not a control. |
| Egress restriction | Network policy and output rendering | The exfiltration half of the trifecta. Allowlist outbound hosts for tools, and be strict about rendering model-supplied URLs, because an image tag is a GET request with attacker-chosen parameters. |
| Resource ceilings | The agent loop and the billing layer | Runaway loops and cost incidents. Maximum iterations, wall-clock timeout, token budget per task, spend cap per user per day. Cheap to add and the reason a bad afternoon does not become a bad invoice. |
| Classifier on input and output | Before the model, and before the response reaches the user | Known-shape content problems and obvious leaks such as secrets or personal data in output. Probabilistic, so it belongs as a layer, never as the boundary. |
| Provenance separation in context | Prompt construction | Reduces, does not eliminate. Clearly marking retrieved content as untrusted data measurably helps. Treat it as defence in depth behind the controls above, not as the plan. |
The pattern that makes untrusted content survivable
When an agent must process content it does not trust, the useful structure is to split the work between two contexts with different privileges.
One model has tools and never sees untrusted text. Another sees the untrusted text and has no tools at all. The privileged side asks the quarantined side questions and receives back constrained values, typed and validated, rather than free text that gets pasted into the next prompt. Instructions hidden in the document reach a model that can do nothing with them.
This costs an extra call and some plumbing, and it is significantly stronger than any amount of prompt hardening. The critical detail is that what crosses the boundary must be schema-constrained and validated, because passing arbitrary text back to the privileged context reopens exactly the hole the split was built to close.
Agent-specific ceilings
- 01
Maximum iterations
A hard cap on tool-call cycles per task, enforced in the loop rather than requested in the prompt. Without it, a model that misreads a tool result can retry indefinitely at full token cost.
- 02
Wall-clock timeout
Independent of iteration count, because one slow tool can hold a task open for an hour inside three iterations.
- 03
Token budget per task
Denominated in money, not tokens, so it means something during an incident. This is what makes a cost spike bounded rather than open-ended.
- 04
Per-user, per-day spend cap
One compromised or automated account should not be able to spend the monthly budget. Enforce at the billing layer, where it cannot be bypassed by any code path.
- 05
Full audit of tool calls
Every call, every argument, the identity it ran as, and the result. During an incident this is the only artefact that answers what actually happened, and it cannot be added retroactively.
Guardrails people route around are not guardrails
A control that blocks legitimate work gets circumvented, and the circumvention is usually invisible to the team that added the control. A confirmation dialogue on every action becomes a reflex click within a day, which removes the protection while leaving the friction and the false confidence.
So confirmations should be reserved for genuinely irreversible operations, and refusals should say what was blocked and offer the legitimate path. Measure false-positive rate on your safety classifier the same way you measure accuracy anywhere else. A filter with a high false-positive rate teaches users to work outside the system, which is a worse security posture than not having it.
How we apply this
In LetX, an AI client reaching a project over MCP is scoped by an OAuth consent that names the specific capabilities granted, and the server checks the caller's actual authorisation on every call rather than trusting anything in the request. Write operations are separated from reads so that granting research access does not grant editing. The reasoning behind that boundary is written up in what it takes to give an agent write access.
Questions
- What are AI guardrails?
- Controls that constrain what an AI system can receive, produce and do. They span input filtering, output filtering, permission enforcement at the tool boundary, resource ceilings, and human confirmation for irreversible actions. The effective ones are enforced in code outside the model; the ones written as prompt instructions are preferences the model can be argued out of.
- Can prompt injection be prevented?
- Not eliminated with current architectures, because a model has no reliable way to separate instructions from data when both are tokens in the same context. It can be made largely harmless. Scope the agent's permissions so a successful injection gains nothing the user did not already have, require confirmation for irreversible actions, restrict outbound network access, and keep untrusted content away from any context that holds tools.
- What is indirect prompt injection?
- Instructions delivered through content the model retrieves rather than through the user's message: a web page, a document, a code comment, an email, an image containing text. It is the more serious form because the attacker is not the user, and the agent acts with the user's permissions when it follows the injected instruction.
- Are guardrail classifiers enough on their own?
- No. A classifier is a probabilistic filter, so it has a false-negative rate against an adversary who gets unlimited attempts to find one. It is a useful layer for known-shape problems and a poor security boundary. Permission scoping and human confirmation are the controls that hold when the classifier is wrong.
- How do I stop an AI agent from leaking private data?
- Break the combination that makes leaking possible: access to private data, exposure to untrusted content, and a way to communicate outward. Remove any one and exfiltration becomes much harder. In practice that means allowlisting outbound destinations, being strict about rendering model-supplied URLs since an image request carries data in its parameters, and keeping untrusted content in a context that has no tools.
- What limits should an agent loop have?
- A hard maximum on iterations, a wall-clock timeout independent of it, a token budget per task expressed in money, and a per-user daily spend cap enforced at the billing layer. All four are enforced in code, because a limit stated in the system prompt is a request rather than a limit.