For ordinary coding tasks, this mainly affects file access, shell commands, Git operations, and local tools. With MegaIndex BrowserAPI, the consequences are broader. A single approved command can connect Claude to a remote browser, restore a session, open an authenticated account, navigate through several pages, download data, or submit a form.
That means browser automation needs two permission layers:
- Claude Code permissions control what the agent can run locally.
- BrowserAPI policies control what the remote browser can do.
The first layer decides whether Claude may launch the task. The second decides what happens after the browser connects.
Why permission modes matter more with a remote browser
Consider this command:
node scripts/check-account.mjs
Locally, it looks harmless. It starts one Node.js process.
Inside the script, however, MegaIndex BrowserAPI may open a remote Chromium session and perform dozens of actions:
- load saved cookies;
- sign in to an account;
- follow redirects;
- open internal pages;
- extract data;
- download a report;
- click a confirmation button.
Claude Code sees the shell command. It does not automatically understand the business meaning of every browser action triggered by that command.
A permission mode can stop Claude from running an unapproved script. It cannot tell whether a button named Confirm applies a filter, publishes a page, deletes a record, or approves a payment.
For that reason, permission modes should be treated as the outer security boundary, not the complete browser policy.
Choosing a mode for BrowserAPI work
Claude Code provides several permission modes, each suited to a different type of task.
| Mode | Best use in a BrowserAPI project |
|---|---|
| Manual | Audits, code review, production accounts, and sensitive browser flows |
| Accept edits | Implementing an already approved Playwright or Puppeteer workflow |
| Plan | Designing multi-step browser automation before changing files |
| Auto | Longer development runs against an isolated staging environment |
| Don’t ask | CI, scheduled checks, and other unattended jobs |
| Bypass permissions | Disposable containers or virtual machines only |
The correct mode depends on more than the number of files being edited. You also need to consider:
- which account the browser uses;
- whether the session contains saved cookies;
- whether the task changes data;
- whether the target is staging or production;
- whether someone will be present to review prompts;
- whether tests can prove that the browser completed the correct action.
Manual mode for review and sensitive sessions
Manual mode is the safest starting point for BrowserAPI projects.
Use it when Claude needs to inspect:
- browser connection code;
- selectors;
- authentication logic;
- session restoration;
- screenshots;
- Playwright traces;
- execution logs;
- retry and timeout handling.
It is also the correct mode for tasks involving:
- production accounts;
- administrative dashboards;
- billing pages;
- personal data;
- publishing interfaces;
- account settings;
- destructive actions.
A reviewer should not silently become an editor. If Claude is checking a BrowserAPI script for errors, it should not also rewrite the script and run it against a live account without a separate decision.
The first execution of any authenticated workflow should remain supervised, even when the code looks straightforward.
Plan mode before complex browser automation
Plan mode is useful when the task involves more than a small selector fix.
Start in plan mode when the workflow:
- touches several files;
- restores an authenticated session;
- visits multiple domains;
- uploads or downloads files;
- includes retries or fallback branches;
- changes account state;
- handles redirects;
- uses persistent browser profiles.
A good BrowserAPI plan should describe the browser flow itself, not only the files Claude intends to edit.
The plan should include:
- the starting URL;
- all permitted domains;
- authentication requirements;
- where credentials and cookies come from;
- read-only actions;
- state-changing actions;
- retry and timeout limits;
- the success condition;
- screenshots, traces, or logs to save;
- session cleanup.
This catches design problems before Claude writes code.
For example, a task described as “download the latest invoice” may actually require opening a billing account, restoring a persistent profile, following an external authentication redirect, and clicking through a page that also contains payment controls.
That should be visible in the plan.
Accept edits for implementation
Once the browser flow has been reviewed, Accept edits is a practical mode for implementation.
Claude can work on:
- Playwright or Puppeteer scripts;
- the BrowserAPI connection module;
- navigation helpers;
- extraction logic;
- retries;
- logging;
- test fixtures;
- screenshot capture;
- session cleanup.
This removes repeated approval prompts for ordinary file changes while keeping execution of more sensitive commands under separate control.
The important part is the review afterward.
Before running the script, inspect the diff for:
- broad selectors such as button or text=Confirm;
- missing hostname checks;
- unlimited retry loops;
- persistent profile reuse;
- credentials written to logs;
- automatic form submission;
- fallback clicks;
- error handlers that continue after an unexpected page state.
Accepting file edits does not mean accepting the resulting browser behavior.
Auto mode belongs in staging
Auto mode is designed for longer tasks where Claude needs to make changes, run commands, inspect failures, and continue without asking after every step.
That can work well with MegaIndex BrowserAPI, but only in a controlled environment.
A suitable auto-mode setup uses:
- a staging website;
- test accounts;
- disposable browser sessions;
- a strict domain allow-list;
- limited credentials;
- fixed action and navigation budgets;
- automatic tests;
- screenshots or traces after important steps.
Auto mode is useful for work such as:
- fixing selectors after a layout change;
- adjusting waits and timeouts;
- rerunning browser tests;
- comparing screenshots;
- debugging extraction failures;
- improving session cleanup.
It is not a good default for production accounts.
A safety classifier may recognize an obviously dangerous command such as a force push or production deployment. It cannot reliably determine whether a normal browser click has the wrong business effect.
This line of code is technically ordinary:
await page.getByRole("button", { name: "Confirm" }).click();
The risk depends entirely on the page.
Auto mode should therefore be paired with browser-side restrictions and a verification hook.
Don’t ask mode for unattended runs
Don’t ask is intended for jobs where nobody is available to approve a prompt.
Typical BrowserAPI cases include:
- scheduled availability checks;
- nightly rendering tests;
- screenshot comparisons;
- browser smoke tests in CI;
- controlled extraction from approved pages;
- regression tests after deployment.
Only explicitly allowed tools should run. Everything else should fail instead of waiting for human input.
The allow-list must be narrow.
Avoid broad rules such as:
Bash node * npm * git
They make it difficult to understand what the unattended job can actually do.
Allow the exact command instead:
Bash(npx playwright test tests/browser/staging*)
The same principle applies to browser scripts. A CI job that only checks page rendering should not receive credentials for an administrative account or access to a persistent browser profile.
Bypass mode requires real isolation
Bypass mode removes the normal permission checks.
It should only be used inside an isolated container or virtual machine with:
- a temporary copy of the project;
- test-only credentials;
- no mounted home directory;
- no production SSH keys;
- no personal cookies;
- no production database access;
- a disposable BrowserAPI profile;
- restricted outbound network access.
A container is not automatically safe.
If it receives production secrets, unrestricted network access, and a persistent browser session, it still has access to production.
Isolation must cover both sides of the workflow:
- the environment where Claude runs;
- the remote browser session that Claude controls.
Permission mode is not a browser permission system
One of the easiest mistakes is assuming that Claude’s permission classifier understands each action inside Playwright or Puppeteer.
It usually does not.
From Claude Code’s perspective, this may be one approved command:
npm run browser:check
Inside the browser, the script may:
- navigate to another domain;
- restore account cookies;
- open a private page;
- upload a file;
- submit a form;
- trigger an irreversible action.
Your BrowserAPI integration needs its own controls.
Add a domain allow-list
Check the hostname before every navigation and after every redirect.
Do not validate only the initial URL. Authentication pages, download links, advertisements, compromised pages, and unexpected redirects may send the browser elsewhere.
Example:
const allowedHosts = new Set([
"staging.example.com",
"accounts.example.com"
]);
function assertAllowedUrl(rawUrl) {
const url = new URL(rawUrl);
if (!allowedHosts.has(url.hostname)) {
throw new Error(`Navigation to unapproved host: ${url.hostname}`);
}
}
page.on("framenavigated", frame => {
if (frame === page.mainFrame()) {
assertAllowedUrl(frame.url());
}
});
This restriction should live in the browser code, where Claude cannot bypass it simply by choosing a different permission mode.
Separate read and write scripts
Do not put every possible browser action into one general-purpose script.
Keep separate entry points for:
- reading and extraction;
- form submission;
- publishing;
- account updates;
- deletion;
- payment-related actions.
A read-only test should not include a helper that can click any element matching arbitrary text.
This also makes permission rules clearer.
For example:
scripts/browser/read-dashboard.mjs scripts/browser/update-profile.mjs scripts/browser/publish-page.mjs
The read-only script may be allowed in CI. The publishing script should always require explicit approval.
Use restricted accounts
The browser account should have only the permissions required for the task.
A test that checks whether a dashboard loads does not need access to:
- billing;
- user management;
- API keys;
- account deletion;
- publishing;
- payment methods.
This reduces the damage caused by a wrong selector, an unexpected redirect, or incorrect AI-generated logic.
Use disposable sessions for autonomous work
Persistent browser profiles are convenient because they retain cookies and authentication.
They also increase risk.
A persistent profile may contain access to unrelated services, saved login state, account history, or sensitive cookies. For autonomous runs, prefer temporary profiles created for one task and destroyed afterward.
Persistent sessions should be reserved for workflows that genuinely require them and should use dedicated test accounts.
Set hard execution limits
A browser agent should not continue indefinitely when it cannot determine whether the task succeeded.
Set limits for:
- total execution time;
- number of navigations;
- number of pages;
- retries per action;
- downloaded file size;
- screenshots;
- browser actions;
- redirected domains.
Example:
const limits = {
maxNavigations: 10,
maxActions: 40,
maxRetriesPerStep: 2,
maxRuntimeMs: 120000
};
When a limit is reached, stop the session and keep the trace for review.
Keep evidence from every important run
A zero exit code only proves that the process ended without reporting an error. It does not prove that the browser completed the intended task.
Keep:
- Playwright traces;
- screenshots;
- final URLs;
- console errors;
- failed network requests;
- action logs;
- extracted output;
- test assertions.
For state-changing workflows, capture the page immediately before and after the action.
Add a Stop hook
Auto mode checks whether an action appears acceptable before it runs. A Stop hook checks whether the resulting code passes verification after Claude finishes.
For a BrowserAPI project, the hook can run the linter and staging browser tests.
Example .claude/settings.json:
{
"permissions": {
"defaultMode": "plan",
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./browser-data/**)",
"Bash(git push --force*)",
"Bash(git remote add *)",
"Bash(git remote set-url *)"
],
"ask": [
"Bash(node scripts/browser/run-production.mjs *)"
],
"allow": [
"Bash(npx playwright test tests/browser/staging*)"
]
},
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/verify-browser-tests.sh",
"timeout": 300
}
]
}
]
}
}
Example .claude/hooks/verify-browser-tests.sh:
#!/usr/bin/env bash
set -uo pipefail
cat >/dev/null
cd "${CLAUDE_PROJECT_DIR:?CLAUDE_PROJECT_DIR is not set}"
if npm run lint && npx playwright test tests/browser/staging; then
exit 0
fi
echo "Browser verification failed." >&2
exit 2
Make the script executable:
chmod +x .claude/hooks/verify-browser-tests.sh
The browser tests should verify more than page availability.
They should confirm:
- the final hostname is allowed;
- the correct test account was used;
- the expected page state is visible;
- no unexpected form was submitted;
- the required output was produced;
- all pages and sessions were closed.
Recommended workflow
A practical policy for MegaIndex BrowserAPI projects looks like this:
| Task | Recommended mode |
|---|---|
| Repository review | Manual |
| Workflow design | Plan |
| Implementation | Accept edits |
| First authenticated run | Manual |
| Repeated staging development | Auto with tests and a Stop hook |
| CI and scheduled checks | Don’t ask with an exact allow-list |
| Disposable experiments | Bypass only inside an isolated container or VM |
| Production changes | Manual |
Prompt for Claude Code
Review this MegaIndex BrowserAPI project and design a safe browser automation workflow. 1. Stay in plan mode. Do not edit files or start a browser session. 2. Identify every file involved in the BrowserAPI connection. 3. List the initial URL, permitted hosts, possible redirects, and external endpoints. 4. Separate read-only actions from actions that change remote state. 5. Identify where credentials, cookies, browser profiles, and session tokens enter the workflow. 6. Define limits for navigation, retries, browser actions, downloads, and total runtime. 7. Define the screenshots, traces, logs, and assertions required to prove success. 8. Specify which staging commands may run automatically. 9. Mark every production, publishing, payment, deletion, or administrative action as approval-required. 10. Return the implementation plan, affected files, risks, tests, and the exact command for the first supervised run.
Final rule
Claude Code permissions control whether an agent can start a BrowserAPI task.
They do not control every action performed inside the remote browser.
Use plan mode to design the workflow, Accept edits to implement it, manual approval for the first authenticated run, auto mode only in staging, and Don’t ask for narrowly defined unattended tests.
The browser itself still needs domain restrictions, limited accounts, execution budgets, disposable sessions, and tests that prove what actually happened.
Discussion