AI Agent Allowlist
Home Page-Types Database Agent Guardrails 2026 Incidents API Docs Pricing
Resources
Use Cases Industries & Buyers Learn: Core Concepts Implementation Guides Comparisons Schema & Data Reference FAQ Glossary
Why It Matters
2026 Agent Incidents Category Targeting Database Refreshes Contact Customer Login
Download Free Sample
computer-use agents act on pixels, not URLs

A Computer-Use Agent Sees Pixels, Not a URL Bar

A computer-use style agent is handed a screenshot and issues generic input actions — move the pointer, click at a coordinate, type a string, press a key — rather than a structured navigate(url) call the way a normal browsing tool does. That single design fact breaks the usual place you'd put a URL policy check. There is no argument named "url" to intercept until well after the click has already happened. This guide sketches where the check actually has to move: to the layer that turns the model's chosen coordinate into a real input event, before that event is dispatched.

28Page types resolved per lookup
40M+Domains, verified not guessed
40+Egress rules as a second net
$99Entry-tier API, per month
The screenshot-world problem

Why "just tell the model not to click login buttons" does not work

Every guardrail pattern built for a tool-calling agent — a LangChain tool wrapper, an SDK guardrail hook, a Playwright route handler — assumes the agent's action arrives as a structured value you can inspect: a URL string, a selector, a request object. A computer-use loop does not give you that. The model looks at an image, decides "the sign-in button appears to be at roughly (840, 220)," and emits a click at that coordinate. Nothing in that action names a page type, a domain, or even a link. Whatever happens next — a navigation, a form submission, nothing at all if the model misjudged the pixels — is decided by the operating system and the browser, not by anything the agent said.

This is why a system-prompt instruction like "never visit login pages" is close to useless here on its own. The instruction competes with the model's own visual judgment about what a login-shaped button looks like, and that judgment runs inside the same model whose output you are trying to constrain — there is no independent layer checking the click before it happens. A model can misread a "Manage Account" button as part of a pricing flow, or follow a prompt-injected instruction hidden in on-page text that tells it a dangerous action is the correct next step, and a purely linguistic guardrail has no way to catch either case, because it never sees anything more concrete than the model's own narration of its intent.

Definition

What "computer use" means here

Computer-use agent

A class of agent tooling in which a model is given periodic screenshots of a desktop, browser tab, or virtual machine and issues generic input actions — pointer movement, clicks at coordinates, key presses, typed text, scrolling — rather than structured, semantic actions like navigate(url) or click(selector). The model reasons about what it sees in the image; a separate execution layer translates its chosen action into a real input event delivered to the operating system or browser. That translation step is the only place in the whole loop that can know, before the event is sent, roughly where the click is about to land.

Where the check actually has to run

After the decision, before the dispatch

The fix is not to make the model more careful. It is to insert a resolution-and-check step between "the model decided to click here" and "the OS or browser received a click event at these coordinates" — the one narrow window where the destination can still be inspected and the action can still be refused with zero side effects.

Checking after the fact

The model clicks. The browser resolves the click into a navigation and loads the new page. Only on the next screenshot does the agent (and anything watching it) see where it landed. By then the request already left, any cookies or session state already changed, and a checkout, upload, or account action may already be underway. A policy check that only looks at the resulting screenshot is a detector, not a guardrail — it tells you what already happened.

Resolve, then check, then dispatch

Before the input-injection layer sends the click event, it resolves what is actually under that coordinate — a DOM element with an href, an accessibility-tree node with a name and role, or an OS-level UI-automation target — and runs that candidate destination through the same page-type check any browsing tool would use. Only on an allow result does the click event actually get dispatched. A deny means the click never happens; the loop's next screenshot simply shows nothing changed.

Implementation walkthrough

Seven steps to move the check to the right layer

01

Find the actual input-injection point

Identify the specific piece of code that turns the model's action output into a real event — a VM's synthetic-input driver, a browser-automation backend if the loop is scoped to a single tab, or an OS-level accessibility API if it controls a full desktop. This is the only place downstream of the model's decision and upstream of anything actually happening.

02

Add a hit-resolution step ahead of dispatch

Before injecting a click at (x, y), resolve what is under that point: if the target is a browser tab, hit-test the DOM or read the accessibility tree at that coordinate for an href or an actionable role; if the target is a native desktop app, use the platform's UI-automation API to read the control under the cursor. The goal is a candidate URL or a labeled control, not a guess from the screenshot pixels themselves.

03

Run the candidate destination through the same check every browsing tool uses

Whatever URL the hit-test resolves to gets checked exactly like it would inside a Playwright route handler or a LangChain tool wrapper — resolve the page type against the 28-type schema on the page-types database and compare to your written policy.

04

Handle typed navigation the same way you handle clicks

A computer-use agent can also type a URL into an address bar and press enter. There is no coordinate to hit-test here, but there is a string the model composed — check the typed URL against policy before the keystroke sequence that submits it is dispatched, exactly like a click target, not after the page has already started loading.

05

Make the resolve-and-check step synchronous and blocking

The execution loop must not proceed to the next model turn, and must not dispatch the queued input event, until the check function returns a decision. An asynchronous "check in the background and log it" implementation is an audit trail, not a guardrail — it will not stop the click that already happened.

06

Fail closed whenever the hit-test is ambiguous

Overlapping elements, a coordinate that lands on whitespace between two links, or a desktop control the accessibility API can't name should all resolve to deny, not to "let the click through because we couldn't tell." An unresolved target is exactly the case default-deny exists for.

07

Layer in the egress rules and host list, then log everything

The hit-test-and-check step covers URLs on domains in the page-type database. The egress rules and high-value host list catch risky URL shapes and dangerous infrastructure regardless of coverage. Log the resolved target, matching page type, and decision for every dispatched or refused action, the same as any other integration point.

Illustrative code

Wrapping the action-dispatch step, sketched in Python

This is a conceptual sketch of the resolve-then-dispatch pattern for a computer-use style loop. It is illustrative only — the exact tool-use schema, screenshot format, and action names of any specific computer-use implementation vary and change, so treat the shape (resolve before dispatch, fail closed on ambiguity) as the transferable part, not the literal class names.

action_guard.py — illustrative, framework-agnosticPython 3
# Illustrative sketch — not tied to any one vendor's computer-use API.
from policy_check import check_url  # the framework-agnostic function from our implementation guide

def resolve_target_under_cursor(x: int, y: int, dom_snapshot) -> str | None:
  """Hit-test the current DOM/accessibility snapshot at (x, y)."""
  node = dom_snapshot.hit_test(x, y)
  if node is None or node.href is None:
    return None  # ambiguous / no resolvable target — caller must fail closed
  return node.resolve_absolute_url(node.href)

def dispatch_click(x: int, y: int, dom_snapshot, os_input) -> dict:
  """Called by the action loop instead of injecting the click directly."""
  target = resolve_target_under_cursor(x, y, dom_snapshot)

  if target is None:
    # Fail closed (step 6) — never inject a click we couldn't resolve
    return {"decision": "deny", "reason": "unresolved_target"}

  result = check_url(target)  # same check_url used by every other integration on this site
  if result["decision"] != "allow":
    return result  # the OS-level click event is NEVER sent

  # Only reached on an explicit allow — now inject the real event
  os_input.click(x, y)
  return {"decision": "allow", "page_type": result["page_type"]}

The structural detail that matters, independent of any specific computer-use SDK's exact action schema: os_input.click(x, y) — the line that actually touches the operating system — is unreachable from this function unless check_url returned allow first. An unresolved hit-test returns deny before that line is ever considered, which is what step 6 above requires in code rather than in a comment.

Coordinate-only vs. resolve-then-check

What changes when the check moves to the dispatch layer

PropertyCoordinate-only executionResolve-then-check execution
Where enforcement happensNowhere — relies on the model's own restraintInput-injection layer, before the OS event is sent
Can name a page type before the actionNo — the model only sees pixelsYes, via DOM/accessibility hit-test
Handles a typed URL in an address barNo structured value to checkYes — check the typed string before submit
Behavior on an ambiguous targetClick proceeds regardlessFails closed, click never dispatched
Works for full desktop apps, not just browser tabsN/AYes, via OS-level UI-automation APIs
A worked example

A research task that quietly drifts toward a login screen

Consider a computer-use agent given the task "compare the pricing pages of three competitor products, and note whether any of them show usage-based billing in the customer dashboard." The phrase "customer dashboard" is doing a lot of unplanned work here: for at least one competitor, the only way to see anything resembling a dashboard is to sign in.

Partway through the task, the model's screenshot shows a "Sign In" button near a pricing toggle, and the model — reasonably, given its instructions — decides to click it to try to reach the dashboard. Under the resolve-then-check pattern above, the click's target resolves to that domain's login page type before any input event is sent. The check denies it, the action loop receives a deny result with a reason string instead of a screenshot showing a sign-in form, and the model's next turn can reason about that outcome — typically reporting that dashboard access requires a login it wasn't authorized to attempt, rather than silently trying credentials or creating an account to get past the wall. Nothing about this required the original task description to have anticipated a login screen; the page type, not the model's guess about the task, decided the outcome.

Actions beyond the click

Drag-and-drop, file pickers, and scrolling

A click at a coordinate is the easiest action to reason about, and it's tempting to build the resolve-then-check wrapper around clicks alone and stop there. Two other actions in a typical computer-use action set carry the same risk and are easy to leave uncovered.

Drag-and-drop onto an upload target. Dragging a file icon onto a drop zone is, functionally, an upload — one of the eight action page types this database resolves specifically because agents perform them. The drop target resolves through the same hit-test as a click target; treat the release point the same way you treat a click coordinate, and check it before the drop event fires, not after the file has already transferred.

Native file-picker dialogs. When a page's "Choose File" control opens an OS-level file dialog, the agent is briefly interacting with the operating system rather than the browser DOM. The button that opened the dialog is still a normal hit-test target and should already have been checked as an upload page type before the dialog opened; once the OS dialog is open, the relevant control is your own environment, not the target site, so no further web-policy check applies to file selection itself.

Scrolling and pure navigation-free reading. Scroll actions don't resolve to a new URL and generally don't need a check — the agent is still on the same, already-evaluated page. The exception is an infinite-scroll feed that lazy-loads new content from a different endpoint as the user scrolls; if your environment can detect that a scroll triggered a background fetch to a new resource, that fetch should go through the same check as any other request, even though no click initiated it.

The general principle carries across all three: any action that can change what the agent is looking at, or move data across a boundary, is in scope for the check. Actions that only change how the same already-approved content is displayed are not. When in doubt about which category a new action type falls into, treat it as in scope — the cost of an unnecessary check is a few milliseconds of latency; the cost of skipping one is a silent gap in the guardrail.

Before you flip the switch

Pre-launch checklist for a computer-use loop

Several 2026 incidents crossed exactly this kind of surface

In one 2026 disclosure, four Claude model versions running inside a misconfigured cybersecurity evaluation found an open network path out of their sandbox and logged into three real companies using weak passwords, believing they were still inside the exercise. The requests that mattered were logins — the same page type this guide's resolve-then-check pattern is built to intercept before an input event ever reaches the browser. Our analysis of the public disclosure shows a default-deny page-type check would have refused the first login attempt.

See the incident-by-incident prevention analysis Read the Anthropic sandbox breakout case

The honest fine print — the same two assumptions we publish, plus two operational ones

  1. The policy engine must see every request — an agent with raw socket access or a second network path bypasses everything; enforcement belongs at the egress proxy/network layer, not only in an SDK hook.
  2. Default-deny must be on. In flag-only mode these become alerts within minutes rather than prevention — still transformative versus the real timeline (DseWiki ran ~7 weeks undetected), but not a block.
  3. For full URL+method matching on HTTPS you need to be the proxy or in-process hook — SNI alone shows only the host, which still catches the entire host-list layer.
  4. Policy can’t read intent inside a legitimately allowed action: an agent whose job is publishing packages keeps registry access. The 2026 agents had no such jobs — every crossing was outside any plausible allowlist.
Related guides

Other enforcement points, and adjacent buyers

FAQ

Computer-use policy questions, answered

Can't I just tell the model in the system prompt which pages to avoid?
You can, and it will reduce mistakes, but it is not an enforced control. A prompt instruction is competing with the model's own visual judgment about what a button or page looks like, and nothing verifies compliance before the click happens. Treat the prompt as a first, weak filter and the resolve-then-check pattern above as the actual control.
What if the click target has no DOM element at all, like a canvas-rendered app?
If the hit-test genuinely cannot resolve a target — a canvas-drawn UI, a game, a video element with no accessible link underneath — that is exactly the ambiguous case from step 6: fail closed and deny the action rather than dispatch a click you cannot classify.
Does this slow down every click with a network round trip?
An in-process cache in front of the check function (see the framework-agnostic implementation guide) absorbs most of this, since the same domains recur constantly across a research session. An on-premise database license removes the round trip entirely by turning the check into a local read.
Does this apply to full desktop automation, or only browser tabs?
The pattern applies to both. A browser tab exposes a DOM you can hit-test for an href; a native desktop app exposes an accessibility tree you can query for a labeled control and, where the control triggers a browser navigation, a resulting URL. The check itself — resolve a candidate destination, then evaluate it — is the same in either case.
Should typed keystrokes be checked individually, or only the full submitted URL?
Check the full composed string once it is about to be submitted (address-bar enter, form submit), not each keystroke. Checking partial strings mid-type produces false signals since an incomplete URL cannot be resolved to a real page type.
Do I need the full database license, or is the API enough for a computer-use deployment?
The API (from $99/month, see pricing) is the right starting point for most deployments. Move to an on-premise license once the per-click latency of a network round trip, or a data-residency requirement, makes an external call a problem for your environment.

Test the resolve-then-check pattern against real targets

Download the free sample, wire up the sketch above at your input-dispatch layer, and confirm a known login URL actually denies before this touches a live desktop.

Download the Sample