Tencent released BrowserSkill, a tool that lets AI agents drive the browser you are already logged into. The obvious story is the capability. The interesting story is a breaking change buried in version 0.3.0.
Before 0.3.0 you could run an agent's browser session unattended by passing --unattended, or tab borrow --no-confirm, or setting BSK_REQUEST_HELP=off. Each one skipped the confirmation prompt that normally asks before the agent takes control of one of your tabs.
In 0.3.0, none of them work any more. They are still accepted, they are deprecated, and they cannot override anything. The only way to disable confirmation now is a toggle in the browser extension's popup.
The flag was being set by the wrong party
Think about who actually writes that flag.
You are not typing bsk tab borrow --no-confirm yourself. An autonomous agent is composing that command, because composing shell commands is the entire interface. So the safety check and the thing being checked were arriving from the same source. The agent asks for permission and, in the same breath, supplies the argument that waives it.
That is not a security boundary. That is a suggestion with extra steps.
Prompt injection makes it concrete. A page your agent reads can contain text aimed at the agent. If a flag can waive confirmation, then the payload only has to convince the model to add six characters to a command it was already going to run. No exploit, no privilege escalation, just a string in a command line.
Authority has to live where the attacker cannot reach
The fix is not a better flag. It is moving the decision out of the channel the attacker can influence.
A browser extension setting is a decision a human made once, deliberately, in a UI no agent can type into. The agent can request; it cannot grant. The asymmetry is the whole point, and it is the same reason sudo prompts on a terminal rather than reading a variable your script set.
The docs are blunt about the cost, too: scripts that relied on those flags alone will now sit waiting for a confirmation nobody answers. They broke working setups on purpose rather than leave a bypass that looked like a feature.
The question to ask of your own agent tooling
Every agent integration eventually grows a "skip the prompt" path, because somebody needs it for CI. Worth asking: can the agent itself set that flag? If yes, it is decoration.
There is a related habit worth keeping. Before pointing an agent at a browser profile, check what that profile actually exposes to a site with the IP checker and decide whether you want an autonomous process acting from it. Most people should use a second profile.
I wrote up the rest of BrowserSkill, including the architecture and how it differs from browser-use and Claude in Chrome, here: BrowserSkill: letting agents use your real browser.
Top comments (3)
The channel argument is right, and the fix has the same gap one level down.
Moving the grant into the extension popup means the agent cannot write it. It does not mean the grant is scoped. A human flips that toggle once, deliberately, and everything after it is authorized, including the action taken four hours later on a page nobody looked at. The decision has become a mode, and modes get inherited by whatever runs next rather than turned off.
Your own analogy has the property that is missing here. sudo does not only prompt on the terminal instead of reading a variable your script set. Its ticket expires, five minutes by default in sudo's own documentation, so a human decision cannot quietly become permanent. That expiry is the second half of the boundary, and a popup toggle does not have it.
What I would want from this class of tool is a grant with an edge on it. A timeout, or a bound set of origins, so the standing state has to be renewed by the party that was allowed to grant it. Otherwise the CI case you mention comes back wearing different clothes. Nobody passes a flag, somebody just leaves the toggle on and forgets.
You're right, and the sudo comparison is the part that stings, because I reached for it and then used only half of it. The ticket expiring is doing as much work as the terminal prompt, and I quietly dropped that half.
Two things from the docs that make your case worse than you put it.
The toggles aren't just a mode, they're a retroactive one. The README says settings save to the browser profile and apply to "existing and new sessions", and that turning confirmation off "releases pending borrow confirmations". So it isn't only inherited by whatever runs next. It reaches into sessions already in flight and answers prompts that were sitting there waiting for a human.
And the expiry you want already exists in the tool, bolted to the wrong noun. There's a
tab borrow --timeout 60s, and it governs how long the confirmation prompt waits for a person, not how long the grant survives.The primitive is right there, pointed at the prompt instead of the permission. Where I'd push back a little is on which half to build first. sudo's five minutes works because a human is at the terminal and re-auth costs nothing. With an agent, nobody's there at 3am, so a TTL mostly means it stops overnight. Correct, and exactly the thing people will switch off. Same failure, different clothes, as you say.
Origin scoping is the half that doesn't need anyone present. The README mentions "task authorization and host approvals" once, in passing, without ever defining them. Feels like the hook is already in there and nobody has hung anything on it yet.
Decay the scope, not the clock.
You are right that wall clock is the wrong measure. I would push on the conclusion rather than the observation.
sudo's timeout does not work because a person is sitting there. It works because the clock is bound to activity and refreshes on use, so the grant dies when the work stops. Wall time is a proxy for that, and a poor one as soon as the actor is not a person. So the fix is not to drop the expiry, it is to hang it on a better noun. The task is the obvious candidate: issue the grant when a task asks for it, revoke it when the task ends, whether that is forty seconds or six hours overnight. Nothing stops at 3am for the wrong reason and nobody has to be awake for it to end. Your own quote suggests the hook is already there, since a README that names task authorization without defining it has picked the right noun and left it empty.
Where I would not follow you all the way is scope on its own. An origin allowlist binds where the agent acts, not what instructs it. The origin you approved this morning serves different bytes this afternoon, and a standing grant on any domain carrying user submitted content is a subscription to being instructed by strangers. Scope decay cannot see that, because the scope never changed.
A grant that ends with the thing that asked for it needs neither a clock nor a person.