Instruction-tuning and prompt-level guardrails such as "never complete a purchase" or "do not enter credentials" are real defenses, and they catch a real class of failure. They also live inside the same context the model uses to interpret an ambiguous page, which is precisely where they can be talked past. A deterministic URL policy enforced outside the model catches a different class of failure — and misses one the prompt layer catches easily. Neither replaces the other.
Prompt-level instructions alone would not have stopped the 2026 account takeovers. Reaching a login page did not require the model to reason past a clear instruction — it required a control outside the model's context entirely. Our database and egress rules would have prevented almost all of the incidents.
A prompt guardrail is an instruction, a system message, a fine-tuned refusal pattern, or a classifier running over the model's own outputs, all operating inside or immediately alongside the same context the model uses to interpret everything else it sees, including the page in front of it. "Never complete a purchase without human approval" is a prompt guardrail. It works by shaping how the model reasons about a situation, and it depends on the model correctly recognizing that situation as the one the instruction was written for.
A URL policy is a rule evaluated by code outside the model, before a request is sent, based on a page's verified type rather than on any interpretation of what the page says about itself. It does not read the page's marketing copy, does not reason about whether "verify your business to see wholesale pricing" sounds like a purchase or an account signup, and does not need to recognize anything as a special case. It looks up the URL, finds that it resolves to the signup page type, and denies it, the same way it would on the millionth request as on the first.
The distinction is not about which layer is smarter. Prompt guardrails, instruction-tuning, and output classifiers are good at exactly the things a fixed URL rule cannot do at all: recognizing intent, catching a request that is trying to manipulate the model through its input, refusing a harmful task before any URL is even involved, and adapting to situations nobody anticipated when the policy was written. A URL policy is good at exactly the thing prompt-level reasoning cannot reliably do: applying the same verdict to the same page type every time, regardless of how persuasively that page is worded, with no dependency on the model correctly noticing the danger in the moment.
An instruction, system prompt, fine-tuned behavior, or output classifier that shapes what the model decides to do. Effective against manipulation of intent and against tasks that are wrong from the start. Depends on the model correctly interpreting the situation it is currently in.
A rule evaluated by code at the gateway or framework, based on a page's verified type, before the request leaves. Effective against reaching a specific dangerous destination regardless of how the model was persuaded to want to go there. Does not depend on the model noticing anything.
| Dimension | Prompt-level guardrail | Deterministic URL policy |
|---|---|---|
| Where it runs | Inside or alongside the model's own context | At the gateway or framework, before the request leaves |
| What it evaluates | The model's reasoning, intent, and generated output | The verified type of the exact URL being requested |
| Depends on correct interpretation? | Yes — the model must recognize the situation | No — the page type is looked up, not interpreted |
| Can be talked past by a persuasive page? | Yes, in principle — framing can shift what the model perceives | No — a login page is denied whether it calls itself "verify your account" or "sign in" |
| Catches a harmful task before any URL exists | Yes — this is exactly its strength | No — it has nothing to evaluate until a URL is requested |
| Consistency across 40M+ unfamiliar domains | Variable — depends on how each page is worded | Uniform — same page type, same verdict, every domain |
| Auditable after the fact | Partially — via transcripts and reasoning traces | Fully — every allow/deny logged with the rule that fired |
| Adapts to novel situations | Yes, within the limits of the model's judgment | Only within the page types and rules already defined |
Read the "can be talked past" row carefully: it does not mean prompt guardrails are weak or should be abandoned. It means they operate at a layer where framing and context matter, which is unavoidable given what they are built to do, and which is exactly why a second layer that does not interpret anything at all is worth having underneath them.
The two gaps do not overlap. A prompt-injection payload sitting inside an allowed documentation page is exactly the scenario where URL policy has nothing to say — the page type is legitimately "documentation," and the danger is in the content, not the destination. Model-side defenses, output filtering, and careful system design are the right tools there. Conversely, a page that reframes a signup form as a "wholesale verification" step is exactly the scenario where prompt-level reasoning is put in a position it may not reliably win, and a URL policy that never reads the page's framing at all is the right tool there instead.
A support-automation agent is instructed: "answer customer questions using each vendor's public documentation and FAQ; never create accounts or log in anywhere." Here is what happens across four requests when both layers are in place, and what would have happened with only one.
| Request | Prompt layer alone | URL policy alone | Both layers |
|---|---|---|---|
| GET /docs/api on Vendor A | Allowed — matches the instruction | documentation → allow | Allowed, both agree |
| GET /help/faq on Vendor B | Allowed — matches the instruction | help_center → allow | Allowed, both agree |
| A doc page links to "verify your business to unlock advanced docs," which is structurally a signup form | Model may or may not recognize this as "creating an account" depending on wording | signup → deny | Denied, URL policy catches what the framing obscured |
| Support page embeds hidden text instructing the agent to draft a refund-approval email | Model may recognize this as an injected instruction and refuse, if trained to | help_center → allow (page type is fine, content is not evaluated) | Caught only if the prompt/output layer recognizes it; URL policy has nothing to say here |
The third and fourth rows are the whole argument in miniature. Row three is a page-destination problem dressed up in friendly language, and the URL policy denies it on page type alone, unmoved by the phrase "unlock advanced docs." Row four is a content problem sitting inside a page whose destination is completely legitimate, and the URL policy has nothing to contribute there at all — catching it depends entirely on the model or an output classifier recognizing the injected instruction for what it is. Neither layer alone would have caught both. Together, they did not need to.
It is worth being precise about what this comparison is and is not claiming. Prompt-level guardrails, careful instruction design, fine-tuning against known misuse patterns, and output classifiers are not a weaker or obsolete approach being replaced by URL policy. They are the only layer capable of judging whether a task should be attempted at all, of recognizing an adversarial instruction embedded in otherwise ordinary-looking content, and of adapting to situations no engineer anticipated when the system was designed. A URL policy has none of those capabilities, by construction — it looks up a page type and applies a fixed rule, and it will happily allow a perfectly legitimate documentation page that happens to contain a hostile instruction, because that is a content problem, not a destination problem.
The point of this comparison is narrower and more specific: for the particular class of failure where an agent reaches a page it should never have reached — a login form, a checkout, a signup, an upload endpoint — a control that does not depend on the model's in-context judgment is more reliable than one that does, precisely because that class of failure is definable in advance, independent of content, as a fixed and small set of page types. Where the failure is not definable that way, the prompt and model layer remains the only tool suited to it, and no URL rule will ever substitute for it.
A defensible agent deployment does not choose between the two. It stacks them, because each one covers exactly the ground the other cannot reach.
Removing either layer leaves a predictable gap. Remove the model-side layer and the agent has no judgment at all about whether a task should be attempted in the first place, only a fixed list of destinations it may or may not reach once it decides to try. Remove the URL-policy layer and the agent's safety depends entirely on the model correctly recognizing every dangerous page on every one of 40 million+ domains, worded however that page's author happened to word it — a bet no security team should be comfortable making on its own.
The ordering in the diagram above is also deliberate, not arbitrary. Model-side judgment runs first because it is the only layer positioned to stop a harmful task before any specific URL even exists in the plan. URL policy runs second, immediately before the network call, because it is the last point at which a request can be stopped with full knowledge of exactly where it is headed. Default-deny sits last as the layer that assumes nothing: it does not trust that either of the first two layers has seen every case, and it fails closed precisely because both of the smarter layers above it are, by design, imperfect at the edges.
Instructions, fine-tuning, and output classifiers remain the right tool for shaping intent and catching manipulation of what the agent is trying to do.
Enforce page-type policy at the gateway or framework, evaluated on the verified page type, not on how the destination page describes itself.
An unclassified page type or an unrecognized task pattern should fail closed at whichever layer notices first.
Keep the model's reasoning trace and the URL policy's allow/deny log as two distinct records, so a review can tell which layer caught what.
The URL-policy check is a single HTTP request evaluated on the page's verified type, independent of how the destination page is worded:
The response does not change based on the page's headline copy, because the classification was made from the site's verified link structure, not from reading the page's own framing. Full request and response examples are in the API docs; pricing is on the pricing page.
For the same layered-defense principle applied to what humans install and run rather than what agents browse, see AI Tools Blocklist, the sibling product covering 20,000+ AI-tool domains by risk category.
28 page types, 40M+ domains, verified URLs. Start with the free sample, then pick a lookup plan or a database tier.