The six tools a browser agent needs
- ›1. A vault that types the password into the page, so it never goes through the prompt.
- ›2. Authenticator codes, made from a saved setup key.
- ›3. An inbox of its own for emailed codes and sign-in links.
- ›4. Saved sessions, so it stays signed in between runs.
- ›5. Approval before risky steps: sending, paying, deleting, changing settings.
- ›6. A log of what it did, and a way to shut it all off.
Option 1: build it from CLIs and libraries
op read reads "the value of the field in 1Password specified by a secret reference", including a one-time password with ?attribute=otp, and writes it to stdout unless you pass --out-file [1]. op run and op inject load secrets into scripts and config files, so they are "never exposed in plaintext" in those files [2].
bw get returns one object from your vault, such as an item, username, password, uri or totp [3]. Unlocking makes a session key, set as BW_SESSION, that "must be used to perform any command that touches vault data" [3].
otpauth is a "One Time Password (HOTP/TOTP) library for Node.js, Deno, Bun and browsers" [4]. speakeasy also makes TOTP codes, and its own repository is marked "NOT MAINTAINED" [5].
Browserbase Contexts "allow you to persist user data across multiple browser sessions" and are encrypted at rest [6]. Its authentication docs suggest logging in once with Session Live View and reusing the context ID [7]. Playwright saves the signed-in state to a file and warns that it "may contain sensitive cookies and headers that could be used to impersonate you or your test account" [8].
Option 2: one identity that holds all six
Each runnerID identity holds a vault of logins that runnerID types into the page, authenticator codes, its own inbox for emailed codes and sign-in links, saved sessions, site rules with approval by email link, and an append-only log. Revoke shuts it all off at once.
Connect it over MCP at https://api.runnerid.torchrunner.ai/mcp (in Claude you sign in on runnerID's own page; Cursor and other clients use your API key as a Bearer token), or add a helper next to the browser. The Browser Use helper installs with pip install runnerid.
npm install @runnerid/stagehand
npm install @runnerid/playwright
pip install runnerid
npx -y @runnerid/mcp-local- ›@runnerid/stagehand and @runnerid/playwright: helpers for your own Stagehand or Playwright code. See /guides/playwright-stagehand-browser-use-login.
- ›runnerid (pip install runnerid): the helper for a Browser Use agent, with the same calls in Python.
- ›@runnerid/mcp-local: a local MCP server for an agent whose browser runnerID can't reach, such as a hosted agent's own cloud machine. It needs RUNNERID_API_KEY and a Chrome with a debugging port, and types the password, authenticator code or emailed code into the open tab without returning it.
The plain difference: where the password and seed go
op read and bw get return the value to the process that runs the command; op read writes to stdout by default [1][3]. If the agent runs the command itself, the password or seed is in the agent's own process. Unless your code keeps it out, it can reach the model's context, tool output or logs. op run and op inject keep secrets out of files, but the script still holds the value [2].
The seed lives in your code or its environment.
The password is typed into the page, and the model never receives it. No. When runnerID can reach the browser, it types the password straight into the page, so it never enters the model, its tool output or its logs. When the browser runs on your own laptop, the helper uses its local route: the password passes through your own code once to be typed, and still never reaches the model.
Tool results never include a password or seed. Only get_email_code and get_authenticator_code return a code, and each release is logged.
1Password also has an agent product that fills without returning values: in a Browserbase session, the 1Password extension "fills and submits forms without returning credential values to your application" [9]. The difference above is with the CLIs, not with 1Password as a company.
The six jobs, one at a time
A vault that types into the page keeps the password out of the prompt. See /guides/stop-pasting-passwords-into-prompts and /guides/cloud-browser-agent-logins.
save_authenticator keeps the setup key encrypted; fill_code types the code into the page, and get_authenticator_code returns only the code to hosted agents. See /guides/authenticator-codes-ai-agents.
Each identity has its own inbox. fill_email_code types an emailed code, and open_magic_link opens a sign-in link only on the site or a trusted subdomain. See /guides/ai-agent-inbox-verification-codes.
save_session and restore_session work over an http, https, ws or wss CDP address runnerID can reach, and a saved session is kept until you save over it, delete it or revoke the identity. See /guides/keep-ai-agent-signed-in.
request_approval emails the owner a link to approve or deny, and every action goes into an append-only log with no secrets. See /guides/human-approval-ai-agent-actions.
Whose account: the agent's own seat
Every login in the toolbelt should be the agent's own seat where the site offers one: a staff account, user permissions or a delegate login. Shopify, Amazon and the IRS tell owners not to share their login, and runnerID is not for bank accounts. See /guides/ai-agent-own-seat-not-your-password.
Which setup fits your agent
Setup steps for each helper are in /guides/playwright-stagehand-browser-use-login.
- ›If runnerID can reach the browser (a hosted browser or one on your own server): Agents that drive a browser runnerID can reach, such as a hosted browser (Browserbase, Steel) or one on your own server, get the strongest mode: runnerID types the password itself.
- ›If the browser is on your own laptop: When the browser runs on your own laptop, the helper uses its local route: the password passes through your own code once to be typed, and still never reaches the model.
- ›If a hosted agent's browser is out of runnerID's reach: Hosted agents that connect over MCP get authenticator and emailed codes returned to them, and approvals and the log work the same. Typing a password into the page needs the runnerID helper next to the browser (Stagehand, Playwright or Browser Use), on a laptop or in a cloud container.
Side by side
- ›CLI or library: op read or bw get returns the value to your process [1][3].
- ›runnerID: fill_login types it into the page; the model never receives it.
- ›CLI or library: op read with ?attribute=otp, bw get totp, or otpauth with the seed in your code [1][3][4].
- ›runnerID: the seed stays encrypted in runnerID; fill_code types the code.
- ›CLI or library: not covered by these tools.
- ›runnerID: the identity's own inbox; fill_email_code types the code.
- ›CLI or library: a Browserbase Context or a Playwright state file [6][8].
- ›runnerID: save_session and restore_session per identity and site; cookie values are not returned.
- ›CLI or library: you build them.
- ›runnerID: approval by email link or console, and an append-only log.
Coming to runnerID
Passkeys, a phone number for SMS codes and agent payment cards are coming to runnerID. Authenticator codes and emailed codes work today.
Questions
What tools does a browser agent need for passwords, logins and 2FA?
Six: a vault that types the password into the page, authenticator codes, an inbox for emailed codes, saved sessions, approval before risky steps, and a log.
Is 1Password CLI or Bitwarden CLI safe for an AI agent?
Both keep the vault encrypted. The value still reaches whatever process runs the command, so keep the agent's model out of that output. With runnerID the password is typed into the page instead. No. When runnerID can reach the browser, it types the password straight into the page, so it never enters the model, its tool output or its logs. When the browser runs on your own laptop, the helper uses its local route: the password passes through your own code once to be typed, and still never reaches the model.
Does the agent ever see my password or seed?
Tool results never include a password or seed. Only get_email_code and get_authenticator_code return a code, and each release is logged.
Can I use this with a hosted agent?
Hosted agents that connect over MCP get authenticator and emailed codes returned to them, and approvals and the log work the same. Typing a password into the page needs the runnerID helper next to the browser (Stagehand, Playwright or Browser Use), on a laptop or in a cloud container.
Should the agent use my own login?
No. Use the staff seat, user permissions or delegate login the site offers. Shopify, Amazon and the IRS tell owners not to share their login. runnerID is not for bank accounts.
What about passkeys and text codes?
Both are coming to runnerID. Authenticator codes and emailed codes work today.
Related guides
Install the helpers and see each case.
Read →Keep the seed out of your code.
Read →Saved sessions compared.
Read →Emailed codes without your personal inbox.
Read →Staff, delegate and service provider seats.
Read →Sources, checked October 24, 2026
- ›1. 1Password CLI, op read: https://www.1password.dev/cli/reference/commands/read
- ›2. 1Password CLI, load secrets into scripts: https://www.1password.dev/cli/secrets-scripts
- ›3. Bitwarden, Password Manager CLI: https://bitwarden.com/help/cli/
- ›4. otpauth on GitHub: https://github.com/hectorm/otpauth
- ›5. speakeasy on GitHub: https://github.com/speakeasyjs/speakeasy
- ›6. Browserbase, Contexts: https://docs.browserbase.com/platform/browser/core-features/contexts
- ›7. Browserbase, Website authentication: https://docs.browserbase.com/platform/identity/authentication
- ›8. Playwright, Authentication: https://playwright.dev/docs/auth
- ›9. Browserbase, 1Password Agentic Autofill: https://docs.browserbase.com/integrations/1password/agentic-autofill
- ›10. runnerID helpers on npm: https://www.npmjs.com/package/@runnerid/stagehand , https://www.npmjs.com/package/@runnerid/playwright , https://www.npmjs.com/package/@runnerid/mcp-local
- ›11. runnerID API docs: https://api.runnerid.torchrunner.ai/llms.txt
1Password is a trademark of AgileBits. Bitwarden is a trademark of Bitwarden, Inc. Browserbase, Steel, Stagehand, Playwright and Browser Use belong to their owners. Chrome is a trademark of Google. Claude is a trademark of Anthropic. Cursor is a trademark of Anysphere. Shopify, Amazon and npm belong to their owners. The otpauth and speakeasy projects belong to their authors. runnerID and Torchrunner are not affiliated with, endorsed by or sponsored by any of them.