Why the headless default lands on a login page
Most browser-agent frameworks start the way Playwright and Puppeteer start: a fresh browser process with an empty profile, usually headless. That is the right default for a test suite. It is the wrong default for "open my billing page and tell me this month's total", because an empty profile has no cookies, no saved logins and no device trust. The agent opens the dashboard, finds a sign-in form, and either stops or starts guessing. If the site uses a passkey, a hardware key or a push to your phone, there is nothing for an agent to type, and the run is over.
The work people actually want to hand off is almost all behind a login: admin consoles, cloud billing, the settings page three menus deep, the form you fill in every week. So the connection question comes before the model question. Here are the four ways to answer it, in the order people usually try them.
1. Copy your profile directory into a new one
The oldest trick: copy User Data (or ~/Library/Application Support/Google/Chrome) somewhere else and launch Chrome with --user-data-dir pointing at the copy and --remote-debugging-port=9222. It used to work. Two things have changed. On Windows, Chrome encrypts cookies with keys bound to the installation and, since Chrome 136, a non-default data directory gets different keys, so the copied cookie database does not decrypt. And copying a live profile while Chrome is running copies a half-written SQLite database. Expect "logged in" to mean "logged in on some sites, until the next restart".
What it keeps: sometimes nothing, sometimes most sessions, depending on OS and version. What it breaks: passkeys and device-bound sessions, which are tied to the real profile, and anything the site re-verifies on a new device fingerprint.
2. A separate --user-data-dir that you log into once
This is what the Chrome team recommends for debugging and what most "connect to CDP" guides describe: a second, dedicated profile with a debug port, which you sign into by hand once and keep around. It is honest and it works for sites with plain password logins.
What it keeps: the sessions you created inside it, for as long as they last. What it breaks: you now maintain a second identity. Every site that expires sessions, every 2FA prompt, every "new device" email happens again in the second profile. Google in particular treats a freshly created automation profile with suspicion. And it still is not the browser you are looking at: your open tabs, your extensions, your password manager are elsewhere. We ran Computron this way for its first weeks; the number of tasks that ended on a login page was the reason we stopped. (The flag itself also stopped working on the default profile in Chrome 136 — the details are here.)
3. Export cookies and storage, import them into the agent's browser
Playwright's storageState and the various auth.json tools do this: connect to a logged-in browser once, dump cookies and local storage, and load them into the fresh headless browser on every run. It is tidy, scriptable, and it keeps the agent's browser isolated from yours.
What it keeps: cookie-based sessions, including HttpOnly cookies, until they expire. What it breaks: everything that is not a cookie. Passkeys live in the OS, not in the file. Sessions that are bound to the device (Chrome's Device Bound Session Credentials are rolling out exactly to stop cookie theft) do not survive the copy by design. Short-lived sessions mean the export goes stale and someone has to refresh it. And the file is a credential: anyone who can read it is you, on every site in it, which is a problem the moment you want to share an agent's workspace or commit anything next to it.
4. An extension bridge into the Chrome you are using
The fourth option is to stop moving sessions around and move the agent instead. A Chrome extension with the debugger permission can attach to a tab in your running, signed-in Chrome and drive it over the DevTools Protocol. The program on your machine reaches the extension through native messaging, which is a local pipe, not a network port. This is how Claude in Chrome talks to Claude Code, and it is how Computron connects by default.
What it keeps: everything, because nothing is copied. The task runs in a tab of your profile: your cookies, your passkeys, your hardware key, your password manager, your extensions. When a site wants a fingerprint touch or a phone tap, the prompt appears in your window and you tap it; the agent waits and continues. What it costs: you install an extension once, and while a task runs Chrome shows the "is debugging this browser" bar. The agent also shares your window, so a well-behaved one should work in its own tab, not steal focus, and attach only for the duration of a task. (In Computron the tab goes into a labelled tab group, the window is brought forward only if you asked to watch, and the extension detaches when the task ends.)
What it cannot do: run while Chrome is closed, or run two agents on the same profile in parallel on two machines. A profile is one process. If you need a fleet of headless browsers for scraping, this is the wrong tool; it is the right tool for the browser you personally use.
Side by side
Copied profile: free, flaky, breaks on encryption and on anything device-bound. Separate profile: reliable for password logins, a second identity to maintain, no passkeys. Exported cookies: clean for CI, stale quickly, a credential file to protect, no passkeys. Extension bridge: your real sessions and your real second factors, one install, one browser at a time.
If the task list is "my dashboards, my settings pages, my forms", the fourth one is the only one that does not hand the login problem back to you.
The special case: logging a CLI in
There is one category of task where the login is the task: gh auth login, gcloud auth login, vercel login, stripe login, and every device-code or OAuth flow that ends with "open this URL and click Authorize". The CLI is waiting in a terminal; the last step lives in a browser; and that browser has to be the one where you are signed into GitHub or Google. A headless profile cannot approve anything. An agent in your logged-in Chrome can open the page, pick the right account, press Authorize, and, for device-code flows, hand the code back to you once. Two rules make this safe: the URL and code are single-use, so nothing about the run should be recorded or replayed, and the code should appear on screen exactly once. Computron treats these runs that way: no learning, no trajectory, secrets scrubbed from logs.
What this means for Computron
Computron is built around option 4 because the other three all end at the same wall. It works in the Chrome you are using, signed in as you, moving the cursor and clicking the way you would, and it stops at the things only you can do (a CAPTCHA, a passkey touch) and carries on when you have done them. The debug port remains as a fallback, and when Computron has to fall back it says so in one line, because that fallback is a different, logged-out browser and you should know. Everything it records stays on your machine as plain text you can read and delete.