Skip to content

Cloud browsing via Browser Use: admin key setting, browser_use tool, live view in web UI - #706

Open
time-attack wants to merge 4 commits into
yc-software:mainfrom
time-attack:browser-use-api-key-setting
Open

Cloud browsing via Browser Use: admin key setting, browser_use tool, live view in web UI#706
time-attack wants to merge 4 commits into
yc-software:mainfrom
time-attack:browser-use-api-key-setting

Conversation

@time-attack

@time-attack time-attack commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

What

Admins can enable cloud browsing for agents by pasting a single Browser Use Cloud API key in the admin UI. When set, agents get a browser_use tool that runs web tasks on Browser Use's hosted browser agent, and the person watching in the web UI sees a collapsible live view of the actual browser (interactive — they can take over, e.g. to complete a sign-in) embedded on the running tool row.

  • Admin setting (browser-use-key, org-scoped): encrypted with the connector key, Postgres-backed, write-only, live-validated against the provider on save, explicit Clear button (no save-empty footgun). Reads back only a configured/not-configured flag derived from decryptability, so key-material rotation can't show "Configured" while agents silently have no tool.
  • browser_use tool (all four harnesses, threaded through HarnessTurnInput like credentialExecServices): POST /api/v4/runs, polls to completion, 15-minute wall clock with remote cancel, abort-safe (mid-poll aborts still cancel the paid run; creation ignores the caller signal so an abort can't orphan an uncancellable run), tolerant of transient poll failures, defensive on unexpected statuses. Completed and failed outputs route through the external-content security screen. Offered only on non-read-only, all-internal turns with an internal actor; strict-posture approval gating applies.
  • Live view: the tool re-emits its tool_call with the live-view URL (origin-validated to https://*.browser-use.com in core); the timeline merges same-callId re-emits into one row; the web UI renders an open collapsible sandboxed iframe (sandbox, referrerpolicy=no-referrer, https-only guard) while running, plain row once settled so stale URLs never reload on replay.

Deliberate scope choices (called out for review)

  • No per-scope ACL grants or admin-tunable spend ceiling yet — the org key is the opt-in and the 15-minute wall clock is the cap. Strict posture still gates each call.
  • Unattended trigger/cron fires may use the tool, matching the existing browse skill's posture.
  • The cloud browser egresses from Browser Use's network, outside org egress policy; the admin card copy discloses this.
  • Dedicated key storage (config-store map) rather than reusing ServiceCredentialStore: the key is consumed core-side (never delivered to sandboxes), wants live validation + a first-class admin card, and scope-config PUTs are already audited.
  • lit's non-keyed message list can recreate the iframe on reattach/history-expand; that reloads the view only — the remote browser session and any in-progress takeover state live server-side.

Review

Reviewed pre-PR by an 8-angle fresh-context pass; all confirmed findings fixed, including: the tool never registering on the pi harness (tool list is built before ref.current exists — now threaded through harness options), unscreened failure text, deferred tool_call breaking replay/turn-resume accounting, iframe sandbox/scheme hardening, admin "Configured" vs undecryptable divergence, and orphaned paid runs on mid-flight aborts.

Testing

  • 239 core tests green locally (pi-tools, browser-use client, admin resource route incl. org-only + validation-rejection + clear, config-store encryption/restart/rotation, orchestrator; Postgres persistence parity runs in CI with DATABASE_URL).
  • web-ui: timeline merge unit tests + live-view source assertions (31 green). admin: card/save/clear assertions (80 green). Typecheck + lint clean everywhere.
  • Not exercised end-to-end: a real Browser Use run needs a live API key, which this environment doesn't have. The no-key state is a strict no-op (no tool, card shows "Not configured"). First live QA will happen on the deploying instance right after sync.

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

…live view

An org admin pastes a Browser Use Cloud API key into a new admin card
(org-scoped, encrypted with the connector key, write-only, live-validated
against the provider on save, Postgres-backed). When the key is set, agents
on every harness gain a browser_use tool that submits the task to Browser
Use's hosted agent (POST /api/v4/runs), polls the run to completion, and
returns the final answer through the external-content security screen. The
tool is offered only on non-read-only turns in all-internal conversations
with an internal actor, and strict-posture approval gating applies like any
other tool.

While a run is active the tool re-emits its tool_call entry with the
provider's interactive live-view URL (validated to an https browser-use.com
origin); the web UI renders it as an open, collapsible, sandboxed iframe on
the running tool row, collapsing to a plain row once the run settles so
stale URLs never reload on replay. The timeline now merges a re-emitted
tool_call into its existing row by callId (rows with a result still get a
fresh row, preserving approval-retry semantics).

Client robustness: caller aborts cancel the remote run even when the abort
lands mid-poll; transient poll failures are tolerated (three consecutive
failures cancel and rethrow); unexpected run statuses resolve as failed
instead of spinning; runs are cancelled at a 15-minute wall clock. The
create call deliberately ignores the caller signal so an abort during
creation cannot orphan an uncancellable run.

Deliberate scope choices: no per-scope ACL grants or admin-tunable spend
ceiling yet (the org key is the opt-in, the wall clock is the cap);
unattended trigger fires may use the tool, matching the browse skill; the
cloud browser egresses from Browser Use's network outside org egress
policy, which the admin card copy discloses.

Also swept per fix-every-instance: the two bare catch-void blocks in
slack/delivery.ts now route through swallow().
…actually draw

While a turn streams, assistant messages render with work=null and in-flight
activity appears only in the bottom live-work dock, so the iframe added to
toolRow() was unreachable exactly when the browser was live. The dock now
embeds the sandboxed live-view iframe under the Browsing line whenever the
active tool call carries an https live view URL — open by default, with the
dock's chevron toggling it. The toolRow branch stays for the paused-on-
approval case, and settled rows still never load the dead URL.
…ndings

The turn's already-granted env secrets (keychain own+standing
materializations and org env-delivery service credentials — exactly the
values the sandbox env already receives, captured at the same two
injection points) become bindable for browser_use. The tool takes
secrets: [{env_key, domains}]; core resolves the value and sends it to
Browser Use as an inline secretBinding the cloud agent can type on the
allowed registrable hostnames but never read. Only env key names and
domains enter the tape; every binding is written to the audit log.

An ungranted env key fails fast naming the granted keys and pointing at
the keychain flow (mint a grant for your own credential, send an ask for
someone else's), so detection -> owner approval -> retry rides the
existing keychain machinery. Bound values are scrubbed out of run
results and provider error echoes (FastAPI 422 bodies quote the
submitted binding) before anything reaches the transcript, and domains
must be registrable hostnames — a bare TLD no longer pins a secret to
the whole of .com.
@MagMueller

Copy link
Copy Markdown

sina, this is sick. happy to help test the live Browser Use path before merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants