# Connect a sandboxed AI agent to Anchor Browser over CDP (https://tenki.cloud/blog/anchor-browser-tenki-sandbox)

> For the complete documentation index, see [llms.txt](https://tenki.cloud/llms.txt)

- Author: Guzman Pintos (Product)
- Published: Sep 22, 2026
- Category: [Sandbox](https://tenki.cloud/blog/category/sandbox)
- Reading time: 8 min

Run your agent in a Tenki Sandbox and drive an Anchor-managed browser with Playwright, with the API key kept out of images, templates and snapshots.

Your agent runs fine in a sandbox until it has to use a real website. You install Chromium, launch it headless, point Playwright at a login page, and get a challenge page instead of a form. Or the agent logs in once, and the next session starts from a clean profile and has to log in again, MFA code and all.

A [Tenki Sandbox](https://tenki.cloud/products/sandbox) gives the agent an isolated Linux VM to run in. It does nothing to make a headless browser on a cloud IP look like a person at a keyboard. [Anchor Browser](https://anchorbrowser.io/) takes on that part: it runs the browser on its side and hands your code a Chrome DevTools Protocol (CDP) URL to connect to. The rest of this post is about when that pairing is worth it, how to get a working session quickly, and where the Anchor API key should and shouldn't live.

## Why your own headless Chrome gets stopped

Sites behind bot-detection services such as Cloudflare, Akamai, DataDome or reCAPTCHA are built to keep automated browsers out, and stock headless Chromium on a cloud IP does nothing to hide that it is one. Logins are the second wall. MFA and session handling assume a human, and a browser profile saved on one VM doesn't follow the agent to the next one unless you store the cookies, or the password, somewhere the next VM can read.

You can build the workaround yourself: a proxy pool, fingerprint patches, a captcha-solving service, a store for browser profiles, and upkeep every time a detection vendor changes something. Anchor sells that layer as a managed browser. Whether that's worth a second vendor depends on how much of your agent's work happens on sites that fight back.

## How the work splits

Tenki's public `tenki/anchor:stable` image is the standard [base image](https://tenki.cloud/docs/sandbox/base-image.md) plus `playwright-core` and an `anchor-smoke` command. It has no local browser, no Anchor API key and no browser profile. Your agent code and the Playwright client run in the sandbox; the browser runs at Anchor, and the two talk over the CDP connection.

Because of that split, every page action is a network round trip. Playwright commands travel from the VM to Anchor and back, so chatty scripts that poll the DOM in tight loops pay for it. The browser also can't see the sandbox: a dev server on `localhost` inside the VM is not reachable from a browser running somewhere else.

The upside is that site logins can stay out of your VM. With Anchor's profiles or Identities, the site's cookies or credentials live on Anchor's side, and the only Anchor secret in the sandbox is the API key.

## What Anchor adds, and what you have to turn on

Anchor lists a set of capabilities for agent browsing. They are Anchor's features and Anchor's claims; check [Anchor's documentation](https://docs.anchorbrowser.io/) for the current details. None of them is switched on in the default session the Tenki example opens. Each one takes a session option, a plan feature, or a request to Anchor.

| Capability                                                                                   | What Anchor says it does                                                                                                       | How you get it                                                                                           |
| -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------- |
| [Anchor Chromium](https://anchorbrowser.io/)                                                 | A Chromium fork that Anchor describes as "fast, stealthy and secure" and "recognized as a human"                               | Anchor's browser; the options below are separate                                                         |
| [Extra Stealth Mode](https://docs.anchorbrowser.io/essentials/stealth)                       | Anti-detection and human-like behavior                                                                                         | `browser.extra_stealth`; Anchor lists it as a Growth plan feature, and it only works with a proxy active |
| [Proxy](https://docs.anchorbrowser.io/advanced/proxy)                                        | Routes the session through Anchor's proxies, with country targeting                                                            | `session.proxy`, off by default                                                                          |
| [Captcha solving](https://docs.anchorbrowser.io/advanced/captcha-solving)                    | Solves captchas during the session                                                                                             | `browser.captcha_solver`, off by default; needs an active proxy or a profile                             |
| [Cloudflare Web Bot Auth](https://docs.anchorbrowser.io/advanced/cloudflare-web-bot-auth)    | Signs requests so Cloudflare can identify the session as Anchor Browser                                                        | `browser.web_bot_auth`, off by default                                                                   |
| [Anchor VPN](https://docs.anchorbrowser.io/advanced/anchor-vpn)                              | Sends browser traffic through Anchor's own network with a dedicated IP                                                         | A premium feature the Anchor team enables on request                                                     |
| [Profiles and Identities](https://docs.anchorbrowser.io/essentials/managed-authentication)   | A profile saves cookies and storage after one manual login; an Identity stores credentials and MFA, and Anchor logs in for you | `browser.profile` or `identities` when you create the session                                            |
| [Web Action Cache](https://anchorbrowser.io/blog/browser-agent-amnesia-skill-caching-anchor) | In Anchor Tasks, replays steps from earlier runs as deterministic code instead of reasoning through every click again          | Part of Anchor Tasks, not a session option                                                               |

If a site blocks you, the table is the place to start. If the problem is logging in, start with profiles and Identities, since they also keep site credentials out of your VM.

## The short path

Create an [Anchor API key](https://app.anchorbrowser.io/api-keys), export it in your local shell, and pass it to the session and nowhere else:

```bash
export ANCHOR_API_KEY=<your-anchor-api-key>

tenki sandbox create \
  --image tenki/anchor:stable \
  --env "ANCHOR_API_KEY=$ANCHOR_API_KEY" \
  --name anchor-demo
```

Then check the whole path before you write any code:

```bash
tenki sandbox exec --session anchor-demo -- anchor-smoke https://example.com
```

`anchor-smoke` creates an Anchor session, connects with Playwright, loads the URL, prints the final URL and page title as JSON, and ends the Anchor session. If that works, the key, the network path and the CDP connection all work.

Your own code follows the same shape: `POST` to Anchor's sessions API, `chromium.connectOverCDP()` on the returned `cdp_url`, and a `DELETE` of the Anchor session in a `finally` block. The [Anchor docs page](https://tenki.cloud/docs/sandbox/anchor.md#use-playwright-in-your-code) has the full script. Because `playwright-core` is installed under `/home/tenki/node_modules`, a script anywhere below `/home/tenki` can import it without another install:

```bash
tenki sandbox write --session anchor-demo --path /home/tenki/agent.mjs --data-file ./agent.mjs
tenki sandbox exec --session anchor-demo -- node /home/tenki/agent.mjs
```

The Tenki example sends an empty body, which gets you a default session. The body is where the options from the table go. Two settings are worth adding early. Anchor's [session API](https://docs.anchorbrowser.io/api-reference/browser-sessions/start-browser-session) defaults to a 20-minute maximum duration and a 5-minute idle timeout, so a long agent task needs a higher `max_duration`. And a named profile lets the agent reuse a login:

```javascript
body: JSON.stringify({
  session: { timeout: { max_duration: 60 } },
  browser: { profile: { name: "crm-login" } },
}),
```

Anchor's docs describe the profile flow: create the session once with `persist: true`, log in, end the session to save the profile, then reuse it by name. Timeouts are in minutes.

Terminate the Tenki session when you're done:

```bash
tenki sandbox terminate anchor-demo
```

## Keep the key out of images, templates and snapshots

Anyone holding the Anchor API key can call Anchor's API as your account, including starting browser sessions. Each of Tenki's reusable artifacts would hand it to more people or keep it around longer than the session that needed it.

Start with images and templates. Anything baked into an image is available to every session launched from it, and images can be published or shared with other workspaces. Template `env` values are plaintext configuration that shows up in read APIs. Template build secrets are encrypted and never reach the runtime, so they are the right tool for a private Git checkout during a build, but not a way to give a running session a key.

Snapshots keep the key around as well. A snapshot captures a session's disk and memory, and a restored session comes back with its running processes and in-memory state. Snapshot a session that has the key, and every session restored from that snapshot starts with it too. If you want a prepared starting point, a template is the tool for that, and the key goes in at session create time.

That leaves the session itself. Tenki's [sessions docs](https://tenki.cloud/docs/sandbox/sessions.md) are blunt that session environment variables are plaintext configuration and not a secret-management channel, and they warn against passing long-lived credentials that way. Passing `ANCHOR_API_KEY` with `--env` is a trade-off you accept for one session at a time, so keep that session short: end it when the work ends (`--max-duration` caps its lifetime), and replace the key in Anchor if you think it leaked. The shell history holds `$ANCHOR_API_KEY`, not the value.

## Pin an exact build

`tenki/anchor:stable` moves to each newly published build. That's fine for trying things out. For an agent you've tested and deployed, the `playwright-core` version under it shouldn't change without you noticing. Resolve the tag once and launch the snapshot it points to:

```bash
tenki sandbox registry resolve tenki/anchor:stable
# image_id    : <image-id>
# snapshot_id : <snapshot-id>

tenki sandbox create --image tenki/anchor@<snapshot-id>
```

A snapshot reference never moves, so it keeps launching that build after `stable` advances. Move to a newer build on purpose, after `anchor-smoke` and your own tests pass on it.

## When you don't need Anchor

A remote, hardened browser solves a problem you may not have. If the site is yours, run your own Chrome inside the sandbox: your own app, staging environment or internal tool doesn't need to be fooled into letting you in. The same goes for testing, because a dev server running in the same VM is reachable on `localhost` from a local browser and not from a remote one. And many sites don't block automation at all. Plenty of documentation sites and public pages load fine in plain headless Chromium.

Running Chrome locally also keeps page content inside your VM and avoids a second bill. [A browser for AI agents: run Chrome in a disposable sandbox](https://tenki.cloud/blog/browser-for-ai-agents-chrome-sandbox) walks through that setup, and the [Chrome docs page](https://tenki.cloud/docs/sandbox/chrome.md) covers headless and headed browsers, CDP and noVNC.

## Next step

Start with the [Anchor docs page](https://tenki.cloud/docs/sandbox/anchor.md): create a session from `tenki/anchor:stable`, run `anchor-smoke`, then swap in your own script. When a site starts blocking you or a login won't stick, turn on the matching option from [Anchor's documentation](https://docs.anchorbrowser.io/).