Rightshold™ Sign up

Answers · agent safety

How do I give a browser-using AI agent per-origin and per-action permissions, and keep cookies and session storage out of the tools the model can see?

Last updated

TL;DR: Put the rules in the code that drives the browser, not in the prompt. Give each task its own browser context and a list of origins it may open (scheme + host + port, not 'anything on example.com'), and for each origin the actions it may take: read, fill a form, click submit, download, upload. Check every navigation, request and action against that list before it runs, and refuse anything off the list. Keep the session out of the model's reach: the tools the model calls should take a target and an action (open this URL, click this element, type into this field) and return page content, never cookies, localStorage, sessionStorage, auth headers or a saved storage-state file. Don't expose raw script evaluation, DevTools Protocol access or 'get cookies' as tools, because those can read session tokens, including HttpOnly cookies, that page scripts can't. Write each allow or deny decision to a record the agent can't edit, so you can show later what it was permitted to do and where.

What should I check, step by step?

1. Start one fresh browser context (or profile) per task, with no saved logins except the ones that task needs. Never point the agent at your everyday browser profile.

  1. Write the task's origin list: exact origins like https://app.example.com, not wildcards, and nothing reached only by redirect. Treat a new origin mid-task as a stop-and-ask, not an allow.
  2. For each origin list the allowed actions (read, fill, submit, download, upload, sign in, pay). Read-only research needs only read; a form task gets fill and submit on that one origin.
  3. Enforce it below the model: check the target URL before every navigation, filter network requests at the browser layer (for example Playwright's context.route), and block service workers so requests can't slip past the filter.
  4. Make the model-facing tools narrow: navigate, click, type, read text, take a screenshot. No tool returns cookies, storage, headers or the storage-state file, and none runs arbitrary JavaScript or DevTools Protocol commands.
  5. Keep saved session files (Playwright storageState and the like) on the host side, out of the agent's working folder, out of git, and out of logs and screenshots.
  6. Redact before anything goes back to the model: strip Authorization, Cookie and Set-Cookie headers, tokens in URLs, and hidden form fields from page content and network logs.
  7. Record every decision (task, origin, action, allow or deny, rule version) outside the agent, and clear the context's cookies and storage when the task ends.

Why can't a browser agent's permissions live in its prompt?

Pages are untrusted input. Anthropic's computer use docs warn that instructions on webpages or in images can override your instructions, and recommend a dedicated VM or container with minimal privileges, keeping account login information away from the model, and limiting internet access to an allowlist of domains.

What do per-origin, per-action permissions look like for a browser agent?

An origin is scheme, host and port together; it's the unit browsers use to separate one site's data from another's. Use it as the unit of permission too, so https://app.example.com doesn't quietly cover https://admin.example.com.

How do I keep cookies and session storage out of the model's view?

A saved browser state is a login. Playwright's authentication docs warn that the storage-state file may contain sensitive cookies and headers that could be used to impersonate you, and say not to check it into any repository. Its saved state covers cookies, localStorage, IndexedDB (when asked) and passkey-based login; sessionStorage needs extra code.

What are the common failure modes?

The agent runs in the user's real browser profile, so it has every session the user has, on every site.

How do I ask Rightshold about this (free, no key)?

Add the MCP server https://www.rightshold.com/mcp to Claude, Cursor, ChatGPT, Grok or VS Code, then ask: “Write down this browser agent's permissions for the task (the exact origins it may open and the actions allowed on each) as a declared intent, so sub-agents can only narrow it and anyone checking later can see what it was allowed.”

One-click setup

{
  "tool": "declare_intent",
  "arguments": {
    "agent_id": "<one of your agents>",
    "purpose": "other",
    "description": "Expense task: read+fill+submit on https://expenses.example.com; read only on https://mail.example.com; no sign-in, payment, upload or other origins",
    "operations": [
      "record_ai_run"
    ],
    "ttl_hours": 4,
    "targets": {
      "domains": [
        "expenses.example.com",
        "mail.example.com"
      ],
      "resources": [
        "action:expenses.example.com:read,fill,submit",
        "action:mail.example.com:read"
      ]
    }
  }
}

Rightshold records declared intents and the decisions your browser driver sends it. It doesn't run, watch or control the browser, and it never needs or stores your cookies or session state. Not legal advice.

What are the sources?

Related

Not legal advice. JSON · Markdown · All answers

Get a free API key in one call

No card and no email needed. 100 free credits; the license and policy checks stay free without a key.

curl -s -X POST https://www.rightshold.com/v1/accounts/signup -H "Content-Type: application/json" -d '{"accept_terms":true}'
export RIGHTSHOLD_API_KEY=rs_...   # the api_key from the reply (shown once)
curl -s https://www.rightshold.com/v1/licenses/check -H "Authorization: Bearer $RIGHTSHOLD_API_KEY" \
  -H "Content-Type: application/json" -d '{"license":"MIT","intended_use":{"commercial_use":true}}'