approve-actions-not-sites
4
min read
Agent Infrastructure
Site-level approval is the default
On Sep 29, 2026, OpenAI added computer use to its Agents API. According to the API changelog, the agent works in an OpenAI-hosted browser, and the developer's application handles website access approvals and sign-in.
That is a reasonable split of duties. The model drives the browser, and the application decides where it may go. But it puts the approval decision at the level of a site. Once the agent is allowed on a store, it is allowed to try anything the store's pages offer: search, checkout, the address book, the button that deletes the account.
Most real tasks need a small part of a page. An agent that checks an order status needs one input and one button. Giving it the whole site is a larger grant than the task requires, and it means the only safeguard against a wrong click is the model's own judgment.
What a page-level action list adds
A finer grain needs a description of the page that exists before the agent acts. Manifest API produces one. You send a URL to POST /manifest, and it reads the page's accessibility tree, cross-references the DOM for details like required fields, input types and disabled states, and returns JSON. The response has the page URL, a short current_page_state, a list of actions, and navigation links.
Each action has an id, a label, a type such as input, textarea or button, a description, and a required flag. A locator with CSS, role and name tells the agent how to find the element. A requires field expresses dependencies between actions as groups combined with AND, where each group lists alternatives. A single required field is a one-item group, and a mutually exclusive pair is a group with two ids.
A simplified example for an order lookup page (illustrative, not a live response):
json
The useful property here is that every control the agent could touch has a name, and the names are data. You can read them, compare them, store them and write rules against them.
An approval rule written against action ids
With a list in hand, an approval rule can be a few lines in your application:
python
The agent plans against the manifest. Before each step, your code checks the chosen id. find_order passes. delete_account does not, and the step is refused or sent to a person for review.
Two things follow from this. First, the policy is readable by someone who does not know the page's markup. A reviewer can see that delete_account is not on the list without opening developer tools. Second, the log is more useful. A record that says the agent chose find_order from five listed actions is easier to audit than a sequence of coordinates or selectors.
Where this falls short
The manifest does not enforce anything. It describes the page. Enforcement depends on your application sitting between the agent's decision and the click, and whether you can intercept individual actions depends on how you drive the browser. Check the Agents API documentation for what your application can see and veto before a step runs. If the hosted browser executes a sequence of steps without returning control, a per-action rule has nowhere to run.
Pages also change. A manifest describes the page at the time it was fetched, so you should fetch a fresh one when the page state changes, such as after a form submit or a route change. An approval list written against stale ids will either block valid steps or miss new controls.
Ids can drift between versions of a site. If you keep long-lived rules, key them on the page URL pattern plus the id, and review them when a site redesigns. A rule that names delete_account helps only while the control still has that id.
Finally, an action list tells you what a control is called, not whether it is dangerous. A button labeled "Confirm" could place an order or dismiss a banner. The description and surrounding context help, but classifying risk is still your policy's job.
Using it
Manifest API is available as an MCP server, io.omfang/manifest, over streamable HTTP, and as a REST endpoint. The free plan includes 50 Manifest calls a month, enough to try the pattern against a few of your own pages. Fetch a manifest for a page you care about, write a short allow list for it, and see how many of its actions the task actually needs.
Sources: OpenAI API changelog, omfang.io.