Repository navigation
secrets in an agent task
If you write a password into a task, you have not handed it to a browser. You have handed it to a conversation, and a conversation has more addresses than people expect.
The model. Whatever is in the task is in the prompt, sent to whoever serves your model, and subject to their retention policy rather than yours. If you are driving from an assistant, that is the assistant's provider.
The transcript. Client-side history, often on disk, often unencrypted, frequently synced. A value typed once lives in every later turn of that conversation, because each turn resends what came before.
The tool call arguments. browser_type takes the text as a parameter, so the
value appears in the call, in whatever the client logs about calls, and in any
debug output.
The page. Where you wanted it, and the only one of the four you intended.
Three out of four are accidental, and none of them is a flaw in any particular tool: it is what "tell the agent your password" means.
A persistent profile. Log in once, by hand, in a headed browser, and keep the profile. The session cookie lives on disk under your control and no credential ever enters a conversation:
STEALTHFOX_PROFILE_DIR=C:/path/to/a/profile-you-keep
This is the right answer for almost every real case, and it is the one getting an AI agent to log into a website already recommends. The task then says "you are already signed in" and never sees a password.
A human step in a headed browser. For anything the profile cannot carry: a code from an app, a hardware key, a login that re-challenges. The agent drives to the login page and stops; you type; it continues. Slower, and correct.
Sometimes there is no profile to lean on, an API key for instance, and then the question is how to limit the damage rather than avoid it.
- Scope it down. A credential that can only read cannot do the thing you are worried about. The account-level argument is in keeping an AI browser agent out of destructive actions.
- Make it short-lived, and revoke it at the end of the run rather than at the end of the quarter.
- Never reuse a personal one. A dedicated credential for automated work means a leak is a revocation rather than an incident.
- Assume the transcript is readable. By you later, by anyone with the machine, by a support process if you ever paste it into one. Write the task as though it will be.
A logged-in page displays your name, your email, sometimes the last four digits of something. Every read the agent takes contains that, and every screenshot paints it.
So even a run with no secret in the task accumulates personal data in the transcript simply by looking at pages. Two consequences worth acting on: scope reads to the region you need rather than taking the whole page, and open any image before it leaves your machine, which is the standing rule in dated screenshots of a page as evidence.
What the reads do with a field you filled. browser_snapshot and
browser_read_html never return the value of a password box, or of a field
whose autocomplete names a secret (current-password, new-password,
one-time-code, cc-csc): they show eight dots, which says the field is filled
and nothing about what with. That still covers a password a "show" button has
turned into plain text, as long as the field carries the token. A field switched
to text with no token reads like any other text box, and its value comes back. A
screenshot paints whatever the page paints.
Obfuscating the secret in the prompt. Base64 or a substitution does not help: the model decodes it, and the decoded value is in the same transcript.
Asking the model not to repeat it. It will mostly comply and it is not a control. The value was already transmitted when you sent it.
Putting it in an environment variable and then reading it into the task. If it ends up in the task, it ends up in all four places. The environment variable only helps if the thing that consumes it is the process, not the conversation: the profile directory above is the example that works.
Is it safe to give an AI agent my password? It goes to the model, the transcript, the tool call and the page. Use a persistent profile and log in by hand instead.
How do I let an agent use a logged-in site without a password? Log in once yourself in a headed browser with a profile directory set, and keep that profile. The session survives and no credential enters the conversation.
What if I need an API key in the run? Scope it to read-only where possible, make it short-lived, use a dedicated one, and revoke it after.
Does hiding or encoding the secret help? No. The model decodes it and the result is in the same transcript.
Is a run without secrets clean? Not automatically. Logged-in pages show personal data, and every read and screenshot captures it.
See also: should you log your AI agent into your accounts, which is the prior question, and what a run should log, where the same data ends up if you are not deliberate about it.
- The four destinations follow from how a tool-using conversation works rather than from a measurement, and the page says so. The profile directory setting is this project's own, documented on the MCP server page.
The whole page is one observation: a task is a message, not a configuration file. Everything else is what follows from that.
- OpenAI Operator alternatives
- Open-source Operator-style agents
- Is OpenAI Operator still available?
- OpenAI Operator vs Claude computer use
- browser-use alternatives
- Choosing an AI browser agent
- Open-source AI browser agents
- Open-source computer-use agents
- What is an AI web agent?
- AI browser agents vs traditional scraping
- Cloud browser infrastructure for AI agents, explained
- Browserbase alternatives
- Firecrawl vs an AI browser agent
- Skyvern alternatives
- Stagehand vs browser-use
- Project Mariner is gone: what replaced it
- Manus alternatives
- Gemini computer use vs Claude computer use
- A stealth browser MCP, reviewed honestly by its own wiki
- AI browser vs AI browser agent: which one do you want?
- AI browser agent vs RPA: which one fits the job
- AI browser agent vs n8n, Zapier and Make
- Vercel agent-browser alternatives, compared honestly
- What is an agentic browser? Definition and the two kinds
- Open-source agentic browsers: the three layers, compared
- Choosing an MCP server for browser automation: four axes
- Stealth MCP servers compared: Camoufox, nodriver, Patchright
- Playwright MCP alternatives, and the three you don't need
- Autonomous browser agents: the four rungs of autonomy
- What is actually free in the AI browser agent stack
- browser-use on GitHub: what the repo actually gives you
- Playwright MCP vs Chrome DevTools MCP: different jobs
- How to choose among MCP servers: a map by category
- Which MCP servers are worth adding to Claude Code
- MCP on GitHub: finding servers and judging them fast
- MCP vs an API: the decision, and what the wrapper costs
- MCP alternatives: when the protocol is the wrong shape
- Why does my AI agent get blocked?
- The timing signal AI agents give off
- Agent retry loops trip rate limits, not fingerprints
- Claude computer use detected as a bot
- browser-use getting blocked: what you can and cannot change
- Playwright MCP session blocked: four causes, four fixes
- Playwright MCP and captchas: what actually gets you past
- Cloudflare and a browser MCP server: what is being read
- Can an AI agent solve a captcha? The honest answer
- Getting an AI agent to fill out forms
- The best model for an MCP browser agent, and what it really costs
- Browser problem or model problem?
- How to use a Playwright MCP server with Claude Code
- Extracting data to a CSV with an AI agent
- Monitoring a page for changes with an AI agent
- How to let Claude Desktop control a browser
- How to add a browser to Cursor as an MCP server
- Using an AI agent to hunt for apartments
- Getting website data into Google Sheets with an AI agent
- Using an AI agent to download invoices from portals
- AI agents for web research
- Using an AI agent to test your own website
- How to add a browser to Cline as an MCP server
- Posting to social media with an AI agent
- Posting to Facebook with an AI agent
- Posting to Instagram with an AI agent
- Posting to X with an AI agent
- Automating LinkedIn posts: read this first
- Appointment bots: what they are and what an agent can legitimately do
- Track prices across sites with an AI agent
- Build a lead list with an AI browser agent
- Run an AI browser agent on a schedule
- AI browser agent with a local LLM: what changes
- Should you log your AI agent into your accounts?
- How to write a task an AI browser agent can follow
- Move data between two web apps with an AI agent
- The MCP server
- How the tools are shaped, and why
- Playwright MCP vs the Playwright CLI: which fits when
- Playwright MCP: browser is already in use, and the fix
- Playwright MCP best practices: four decisions that matter
- Playwright MCP with a proxy, and the three leaks it leaves
- A browser MCP server in GitHub Copilot: setup and limits
- Using a browser MCP server for web scraping: the pattern
- Which LLM for browser automation: the four properties
- How to build a browser agent, and what to take instead
- Getting an AI agent to log into a website: three routes
- MCP tools, resources and prompts: who controls each
- How many MCP tools is too many? The context arithmetic
- How to build an MCP server: the decisions, not the scaffold
- Local or remote MCP server: what changes, and what does not
- Writing an MCP client in Python: the thirty-line version
- Self-hosted AI agent: what one actually costs to run
- How long an AI browser agent takes per step, measured
- Text, HTML, snapshot or screenshot: what the agent should read
- Giving an AI browser agent a stopping condition
- Keeping an AI browser agent out of destructive actions
- Why did the AI agent click the wrong thing
- When the page changes under the AI agent
- Running one AI agent task across a list of sites
- Seeing a page as it appears in another country
- Getting data out of a dashboard with no export button
- Two browsers in one session: main and support
- Finding the dead links on a site with an AI agent
- Filling a CRM record from a company's website
- One form submission per spreadsheet row, with an AI agent
- Dated screenshots of a page as evidence
- Checking order and delivery status with an AI agent
- Reading a PDF that opens inside the browser
- Summarising a long page or thread with an AI agent
- Collecting every image on a page with its caption
- Collecting event and course listings with an AI agent
- Cancelling a subscription with an AI agent
- What an AI agent can and cannot do inside an iframe
- Shadow DOM and an AI agent: you can click it, you cannot read it
- How to add a browser to Codex as an MCP server
- What a page snapshot costs, per control
- How to let Gemini CLI use a browser
- Native selects and the ones that only look like selects
- Clicking by selector or by coordinates
- How long the agent waits before it gives up
- What a second browser costs
- Uploading a file with an AI agent, and why this one cannot
- Watching the agent work, and when it is worth it
- When not to use an AI browser agent
- Agent or script: deciding once instead of every time
- Using the keyboard instead of the mouse
- Secrets in an agent task: where they end up
- What an agent run should log
- Deduplicating what an AI agent collects
- Normalising values across sites
- Validating an AI agent's output
- Reading a table with an AI agent
- Driving a site's own search and filters
- The task works headed and fails headless
- How to let the AdaL CLI use a browser