Merge branch 'main' into nanogpt
This commit is contained in:
317 files changed
+6416
-23143
No files matched your search
@@ -115,6 +115,9 @@ body::after {
|
||||
}
|
||||
|
||||
.shell {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
padding: 22px 16px 10px;
|
||||
}
|
||||
|
||||
|
||||
@@ -218,6 +218,7 @@ Prefer `chat_guid` for stable routing:
|
||||
## Security
|
||||
- Webhook requests are authenticated by comparing `guid`/`password` query params or headers against `channels.bluebubbles.password`. Requests from `localhost` are also accepted.
|
||||
- Keep the API password and webhook endpoint secret (treat them like credentials).
|
||||
- Localhost trust means a same-host reverse proxy can unintentionally bypass the password. If you proxy the gateway, require auth at the proxy and configure `gateway.trustedProxies`. See [Gateway security](/gateway/security#reverse-proxy-configuration).
|
||||
- Enable HTTPS + firewall rules on the BlueBubbles server if exposing it outside your LAN.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
@@ -298,8 +298,12 @@ ack reaction after the bot replies.
|
||||
- `guilds."*"`: default per-guild settings applied when no explicit entry exists.
|
||||
- `guilds.<id>.slug`: optional friendly slug used for display names.
|
||||
- `guilds.<id>.users`: optional per-guild user allowlist (ids or names).
|
||||
- `guilds.<id>.tools`: optional per-guild tool policy overrides (`allow`/`deny`/`alsoAllow`) used when the channel override is missing.
|
||||
- `guilds.<id>.toolsBySender`: optional per-sender tool policy overrides at the guild level (applies when the channel override is missing; `"*"` wildcard supported).
|
||||
- `guilds.<id>.channels.<channel>.allow`: allow/deny the channel when `groupPolicy="allowlist"`.
|
||||
- `guilds.<id>.channels.<channel>.requireMention`: mention gating for the channel.
|
||||
- `guilds.<id>.channels.<channel>.tools`: optional per-channel tool policy overrides (`allow`/`deny`/`alsoAllow`).
|
||||
- `guilds.<id>.channels.<channel>.toolsBySender`: optional per-sender tool policy overrides within the channel (`"*"` wildcard supported).
|
||||
- `guilds.<id>.channels.<channel>.users`: optional per-channel user allowlist.
|
||||
- `guilds.<id>.channels.<channel>.skills`: skill filter (omit = all skills, empty = none).
|
||||
- `guilds.<id>.channels.<channel>.systemPrompt`: extra system prompt for the channel (combined with channel topic).
|
||||
|
||||
@@ -10,7 +10,7 @@ on any homeserver, so you need a Matrix account for the bot. Once it is logged i
|
||||
the bot directly or invite it to rooms (Matrix "groups"). Beeper is a valid client option too,
|
||||
but it requires E2EE to be enabled.
|
||||
|
||||
Status: supported via plugin (matrix-bot-sdk). Direct messages, rooms, threads, media, reactions,
|
||||
Status: supported via plugin (@vector-im/matrix-bot-sdk). Direct messages, rooms, threads, media, reactions,
|
||||
polls (send + poll-start as text), location, and E2EE (with crypto support).
|
||||
|
||||
## Plugin required
|
||||
|
||||
@@ -421,8 +421,12 @@ Key settings (see `/gateway/configuration` for shared channel patterns):
|
||||
- `channels.msteams.replyStyle`: `thread | top-level` (see [Reply Style](#reply-style-threads-vs-posts)).
|
||||
- `channels.msteams.teams.<teamId>.replyStyle`: per-team override.
|
||||
- `channels.msteams.teams.<teamId>.requireMention`: per-team override.
|
||||
- `channels.msteams.teams.<teamId>.tools`: default per-team tool policy overrides (`allow`/`deny`/`alsoAllow`) used when a channel override is missing.
|
||||
- `channels.msteams.teams.<teamId>.toolsBySender`: default per-team per-sender tool policy overrides (`"*"` wildcard supported).
|
||||
- `channels.msteams.teams.<teamId>.channels.<conversationId>.replyStyle`: per-channel override.
|
||||
- `channels.msteams.teams.<teamId>.channels.<conversationId>.requireMention`: per-channel override.
|
||||
- `channels.msteams.teams.<teamId>.channels.<conversationId>.tools`: per-channel tool policy overrides (`allow`/`deny`/`alsoAllow`).
|
||||
- `channels.msteams.teams.<teamId>.channels.<conversationId>.toolsBySender`: per-channel per-sender tool policy overrides (`"*"` wildcard supported).
|
||||
- `channels.msteams.sharePointSiteId`: SharePoint site ID for file uploads in group chats/channels (see [Sending files in group chats](#sending-files-in-group-chats)).
|
||||
|
||||
## Routing & Sessions
|
||||
|
||||
@@ -464,6 +464,8 @@ For fine-grained control, use these tags in agent responses:
|
||||
Channel options (`channels.slack.channels.<id>` or `channels.slack.channels.<name>`):
|
||||
- `allow`: allow/deny the channel when `groupPolicy="allowlist"`.
|
||||
- `requireMention`: mention gating for the channel.
|
||||
- `tools`: optional per-channel tool policy overrides (`allow`/`deny`/`alsoAllow`).
|
||||
- `toolsBySender`: optional per-sender tool policy overrides within the channel (keys are sender ids/@handles/emails; `"*"` wildcard supported).
|
||||
- `allowBots`: allow bot-authored messages in this channel (default: false).
|
||||
- `users`: optional per-channel user allowlist.
|
||||
- `skills`: skill filter (omit = all skills, empty = none).
|
||||
|
||||
@@ -529,6 +529,7 @@ Provider options:
|
||||
- `channels.telegram.streamMode`: `off | partial | block` (draft streaming).
|
||||
- `channels.telegram.mediaMaxMb`: inbound/outbound media cap (MB).
|
||||
- `channels.telegram.retry`: retry policy for outbound Telegram API calls (attempts, minDelayMs, maxDelayMs, jitter).
|
||||
- `channels.telegram.network.autoSelectFamily`: override Node autoSelectFamily (true=enable, false=disable). Defaults to disabled on Node 22 to avoid Happy Eyeballs timeouts.
|
||||
- `channels.telegram.proxy`: proxy URL for Bot API calls (SOCKS/HTTP).
|
||||
- `channels.telegram.webhookUrl`: enable webhook mode.
|
||||
- `channels.telegram.webhookSecret`: webhook secret (optional).
|
||||
|
||||
+10
-12
@@ -1,8 +1,8 @@
|
||||
---
|
||||
summary: "CLI reference for `clawdbot browser` (profiles, tabs, actions, extension relay, remote serve)"
|
||||
summary: "CLI reference for `clawdbot browser` (profiles, tabs, actions, extension relay)"
|
||||
read_when:
|
||||
- You use `clawdbot browser` and want examples for common tasks
|
||||
- You want to control a remote browser via `browser.controlUrl`
|
||||
- You want to control a browser running on another machine via a node host
|
||||
- You want to use the Chrome extension relay (attach/detach via toolbar button)
|
||||
---
|
||||
|
||||
@@ -16,8 +16,10 @@ Related:
|
||||
|
||||
## Common flags
|
||||
|
||||
- `--url <controlUrl>`: override `browser.controlUrl` for this command invocation.
|
||||
- `--browser-profile <name>`: choose a browser profile (default comes from config).
|
||||
- `--url <gatewayWsUrl>`: Gateway WebSocket URL (defaults to config).
|
||||
- `--token <token>`: Gateway token (if required).
|
||||
- `--timeout <ms>`: request timeout (ms).
|
||||
- `--browser-profile <name>`: choose a browser profile (default from config).
|
||||
- `--json`: machine-readable output (where supported).
|
||||
|
||||
## Quick start (local)
|
||||
@@ -93,14 +95,10 @@ Then Chrome → `chrome://extensions` → enable “Developer mode” → “Loa
|
||||
|
||||
Full guide: [Chrome extension](/tools/chrome-extension)
|
||||
|
||||
## Remote browser control (`clawdbot browser serve`)
|
||||
## Remote browser control (node host proxy)
|
||||
|
||||
If the Gateway runs on a different machine than the browser, run a standalone browser control server on the machine that runs Chrome:
|
||||
If the Gateway runs on a different machine than the browser, run a **node host** on the machine that has Chrome/Brave/Edge/Chromium. The Gateway will proxy browser actions to that node (no separate browser control server required).
|
||||
|
||||
```bash
|
||||
clawdbot browser serve --bind 127.0.0.1 --port 18791 --token <token>
|
||||
```
|
||||
Use `gateway.nodes.browser.mode` to control auto-routing and `gateway.nodes.browser.node` to pin a specific node if multiple are connected.
|
||||
|
||||
Then point the Gateway at it using `browser.controlUrl` + `browser.controlToken` (or `CLAWDBOT_BROWSER_CONTROL_TOKEN`).
|
||||
|
||||
Security + TLS best-practices: [Browser tool](/tools/browser), [Tailscale](/gateway/tailscale), [Security](/gateway/security)
|
||||
Security + remote setup: [Browser tool](/tools/browser), [Remote access](/gateway/remote), [Tailscale](/gateway/tailscale), [Security](/gateway/security)
|
||||
+1
-2
@@ -860,9 +860,8 @@ Location:
|
||||
Browser control CLI (dedicated Chrome/Brave/Edge/Chromium). See [`clawdbot browser`](/cli/browser) and the [Browser tool](/tools/browser).
|
||||
|
||||
Common options:
|
||||
- `--url <controlUrl>`
|
||||
- `--url`, `--token`, `--timeout`, `--json`
|
||||
- `--browser-profile <name>`
|
||||
- `--json`
|
||||
|
||||
Manage:
|
||||
- `browser status`
|
||||
|
||||
@@ -232,6 +232,42 @@ Notes:
|
||||
- Discord defaults live in `channels.discord.guilds."*"` (overridable per guild/channel).
|
||||
- Group history context is wrapped uniformly across channels and is **pending-only** (messages skipped due to mention gating); use `messages.groupChat.historyLimit` for the global default and `channels.<channel>.historyLimit` (or `channels.<channel>.accounts.*.historyLimit`) for overrides. Set `0` to disable.
|
||||
|
||||
## Group/channel tool restrictions (optional)
|
||||
Some channel configs support restricting which tools are available **inside a specific group/room/channel**.
|
||||
|
||||
- `tools`: allow/deny tools for the whole group.
|
||||
- `toolsBySender`: per-sender overrides within the group (keys are sender IDs/usernames/emails/phone numbers depending on the channel). Use `"*"` as a wildcard.
|
||||
|
||||
Resolution order (most specific wins):
|
||||
1) group/channel `toolsBySender` match
|
||||
2) group/channel `tools`
|
||||
3) default (`"*"`) `toolsBySender` match
|
||||
4) default (`"*"`) `tools`
|
||||
|
||||
Example (Telegram):
|
||||
|
||||
```json5
|
||||
{
|
||||
channels: {
|
||||
telegram: {
|
||||
groups: {
|
||||
"*": { tools: { deny: ["exec"] } },
|
||||
"-1001234567890": {
|
||||
tools: { deny: ["exec", "read", "write"] },
|
||||
toolsBySender: {
|
||||
"123456789": { alsoAllow: ["exec"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Notes:
|
||||
- Group/channel tool restrictions are applied in addition to global/agent tool policy (deny still wins).
|
||||
- Some channels use different nesting for rooms/channels (e.g., Discord `guilds.*.channels.*`, Slack `channels.*`, MS Teams `teams.*.channels.*`).
|
||||
|
||||
## Group allowlists
|
||||
When `channels.whatsapp.groups`, `channels.telegram.groups`, or `channels.imessage.groups` is configured, the keys act as a group allowlist. Use `"*"` to allow all groups while still setting default mention behavior.
|
||||
|
||||
|
||||
+6
-4
@@ -345,10 +345,6 @@
|
||||
"source": "/auth-monitoring",
|
||||
"destination": "/automation/auth-monitoring"
|
||||
},
|
||||
{
|
||||
"source": "/scripts",
|
||||
"destination": "/scripts"
|
||||
},
|
||||
{
|
||||
"source": "/camera",
|
||||
"destination": "/nodes/camera"
|
||||
@@ -805,6 +801,10 @@
|
||||
"source": "/install/railway/",
|
||||
"destination": "/railway"
|
||||
},
|
||||
{
|
||||
"source": "/install/northflank/",
|
||||
"destination": "/northflank"
|
||||
},
|
||||
{
|
||||
"source": "/gcp",
|
||||
"destination": "/platforms/gcp"
|
||||
@@ -852,6 +852,7 @@
|
||||
"install/docker",
|
||||
"railway",
|
||||
"render",
|
||||
"northflank",
|
||||
"install/bun"
|
||||
]
|
||||
},
|
||||
@@ -955,6 +956,7 @@
|
||||
"gateway/doctor",
|
||||
"gateway/logging",
|
||||
"gateway/security",
|
||||
"security/formal-verification",
|
||||
"gateway/sandbox-vs-tool-policy-vs-elevated",
|
||||
"gateway/sandboxing",
|
||||
"gateway/troubleshooting",
|
||||
|
||||
@@ -954,6 +954,8 @@ Notes:
|
||||
- `commands.debug: true` enables `/debug` (runtime-only overrides).
|
||||
- `commands.restart: true` enables `/restart` and the gateway tool restart action.
|
||||
- `commands.useAccessGroups: false` allows commands to bypass access-group allowlists/policies.
|
||||
- Slash commands and directives are only honored for **authorized senders**. Authorization is derived from
|
||||
channel allowlists/pairing plus `commands.useAccessGroups`.
|
||||
|
||||
### `web` (WhatsApp web channel runtime)
|
||||
|
||||
@@ -1027,6 +1029,9 @@ Set `channels.telegram.configWrites: false` to block Telegram-initiated config w
|
||||
maxDelayMs: 30000,
|
||||
jitter: 0.1
|
||||
},
|
||||
network: { // transport overrides
|
||||
autoSelectFamily: false
|
||||
},
|
||||
proxy: "socks5://localhost:9050",
|
||||
webhookUrl: "https://example.com/telegram-webhook",
|
||||
webhookSecret: "secret",
|
||||
@@ -2754,7 +2759,7 @@ Example:
|
||||
|
||||
### `browser` (clawd-managed browser)
|
||||
|
||||
Clawdbot can start a **dedicated, isolated** Chrome/Brave/Edge/Chromium instance for clawd and expose a small loopback control server.
|
||||
Clawdbot can start a **dedicated, isolated** Chrome/Brave/Edge/Chromium instance for clawd and expose a small loopback control service.
|
||||
Profiles can point at a **remote** Chromium-based browser via `profiles.<name>.cdpUrl`. Remote
|
||||
profiles are attach-only (start/stop/reset are disabled).
|
||||
|
||||
@@ -2763,8 +2768,9 @@ scheme/host for profiles that only set `cdpPort`.
|
||||
|
||||
Defaults:
|
||||
- enabled: `true`
|
||||
- control URL: `http://127.0.0.1:18791` (CDP uses `18792`)
|
||||
- CDP URL: `http://127.0.0.1:18792` (control URL + 1, legacy single-profile)
|
||||
- evaluateEnabled: `true` (set `false` to disable `act:evaluate` and `wait --fn`)
|
||||
- control service: loopback only (port derived from `gateway.port`, default `18791`)
|
||||
- CDP URL: `http://127.0.0.1:18792` (control service + 1, legacy single-profile)
|
||||
- profile color: `#FF4500` (lobster-orange)
|
||||
- Note: the control server is started by the running gateway (Clawdbot.app menubar, or `clawdbot gateway`).
|
||||
- Auto-detect order: default browser if Chromium-based; otherwise Chrome → Brave → Edge → Chromium → Chrome Canary.
|
||||
@@ -2773,7 +2779,7 @@ Defaults:
|
||||
{
|
||||
browser: {
|
||||
enabled: true,
|
||||
controlUrl: "http://127.0.0.1:18791",
|
||||
evaluateEnabled: true,
|
||||
// cdpUrl: "http://127.0.0.1:18792", // legacy single-profile override
|
||||
defaultProfile: "chrome",
|
||||
profiles: {
|
||||
|
||||
@@ -83,13 +83,13 @@ Defaults (can be overridden via env/flags/config):
|
||||
- `CLAWDBOT_STATE_DIR=~/.clawdbot-dev`
|
||||
- `CLAWDBOT_CONFIG_PATH=~/.clawdbot-dev/clawdbot.json`
|
||||
- `CLAWDBOT_GATEWAY_PORT=19001` (Gateway WS + HTTP)
|
||||
- `browser.controlUrl=http://127.0.0.1:19003` (derived: `gateway.port+2`)
|
||||
- browser control service port = `19003` (derived: `gateway.port+2`, loopback only)
|
||||
- `canvasHost.port=19005` (derived: `gateway.port+4`)
|
||||
- `agents.defaults.workspace` default becomes `~/clawd-dev` when you run `setup`/`onboard` under `--dev`.
|
||||
|
||||
Derived ports (rules of thumb):
|
||||
- Base port = `gateway.port` (or `CLAWDBOT_GATEWAY_PORT` / `--port`)
|
||||
- `browser.controlUrl port = base + 2` (or `CLAWDBOT_BROWSER_CONTROL_URL` / config override)
|
||||
- browser control service port = base + 2 (loopback only)
|
||||
- `canvasHost.port = base + 4` (or `CLAWDBOT_CANVAS_HOST_PORT` / config override)
|
||||
- Browser profile CDP ports auto-allocate from `browser.controlPort + 9 .. + 108` (persisted per profile).
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ clawdbot --profile rescue gateway install
|
||||
|
||||
Base port = `gateway.port` (or `CLAWDBOT_GATEWAY_PORT` / `--port`).
|
||||
|
||||
- `browser.controlUrl port = base + 2`
|
||||
- browser control service port = base + 2 (loopback only)
|
||||
- `canvasHost.port = base + 4`
|
||||
- Browser profile CDP ports auto-allocate from `browser.controlPort + 9 .. + 108`
|
||||
|
||||
@@ -81,8 +81,8 @@ If you override any of these in config or env, you must keep them unique per ins
|
||||
|
||||
## Browser/CDP notes (common footgun)
|
||||
|
||||
- Do **not** pin `browser.controlUrl` or `browser.cdpUrl` to the same values on multiple instances.
|
||||
- Each instance needs its own browser control port and CDP range.
|
||||
- Do **not** pin `browser.cdpUrl` to the same values on multiple instances.
|
||||
- Each instance needs its own browser control port and CDP range (derived from its gateway port).
|
||||
- If you need explicit CDP ports, set `browser.profiles.<name>.cdpPort` per instance.
|
||||
- Remote Chrome: use `browser.profiles.<name>.cdpUrl` (per profile, per instance).
|
||||
|
||||
|
||||
@@ -117,6 +117,6 @@ Short version: **keep the Gateway loopback-only** unless you’re sure you need
|
||||
- `gateway.remote.tlsFingerprint` pins the remote TLS cert when using `wss://`.
|
||||
- **Tailscale Serve** can authenticate via identity headers when `gateway.auth.allowTailscale: true`.
|
||||
Set it to `false` if you want tokens/passwords instead.
|
||||
- Treat `browser.controlUrl` like an admin API: tailnet-only + token auth.
|
||||
- Treat browser control like operator access: tailnet-only + deliberate node pairing.
|
||||
|
||||
Deep dive: [Security](/gateway/security).
|
||||
@@ -59,6 +59,8 @@ Two layers matter:
|
||||
Rules of thumb:
|
||||
- `deny` always wins.
|
||||
- If `allow` is non-empty, everything else is treated as blocked.
|
||||
- Tool policy is the hard stop: `/exec` cannot override a denied `exec` tool.
|
||||
- `/exec` only changes session defaults for authorized senders; it does not grant tool access.
|
||||
Provider tool keys accept either `provider` (e.g. `google-antigravity`) or `provider/model` (e.g. `openai/gpt-5.2`).
|
||||
|
||||
### Tool groups (shorthands)
|
||||
@@ -95,6 +97,7 @@ Elevated does **not** grant extra tools; it only affects `exec`.
|
||||
- Use `/elevated full` to skip exec approvals for the session.
|
||||
- If you’re already running direct, elevated is effectively a no-op (still gated).
|
||||
- Elevated is **not** skill-scoped and does **not** override tool allow/deny.
|
||||
- `/exec` is separate from elevated. It only adjusts per-session exec defaults for authorized senders.
|
||||
|
||||
Gates:
|
||||
- Enablement: `tools.elevated.enabled` (and optionally `agents.list[].tools.elevated.enabled`)
|
||||
|
||||
@@ -142,6 +142,8 @@ Tool allow/deny policies still apply before sandbox rules. If a tool is denied
|
||||
globally or per-agent, sandboxing doesn’t bring it back.
|
||||
|
||||
`tools.elevated` is an explicit escape hatch that runs `exec` on the host.
|
||||
`/exec` directives only apply for authorized senders and persist per session; to hard-disable
|
||||
`exec`, use tool policy deny (see [Sandbox vs Tool Policy vs Elevated](/gateway/sandbox-vs-tool-policy-vs-elevated)).
|
||||
|
||||
Debugging:
|
||||
- Use `clawdbot sandbox explain` to inspect effective sandbox mode, tool policy, and fix-it config keys.
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
title: Formal Verification (Security Models)
|
||||
summary: Redirect to the canonical Formal Verification page.
|
||||
permalink: /gateway/security/formal-verification/
|
||||
---
|
||||
|
||||
This page moved to: [/security/formal-verification/](/security/formal-verification/)
|
||||
|
||||
<script>
|
||||
// Best-effort client-side redirect for Mintlify/Next.
|
||||
window.location.replace("/security/formal-verification/");
|
||||
</script>
|
||||
+28
-21
@@ -7,6 +7,8 @@ read_when:
|
||||
|
||||
## Quick check: `clawdbot security audit`
|
||||
|
||||
See also: [Formal Verification (Security Models)](/security/formal-verification/)
|
||||
|
||||
Run this regularly (especially after changing config or exposing network surfaces):
|
||||
|
||||
```bash
|
||||
@@ -36,7 +38,7 @@ Start with the smallest access that still works, then widen it as you gain confi
|
||||
- **Inbound access** (DM policies, group policies, allowlists): can strangers trigger the bot?
|
||||
- **Tool blast radius** (elevated tools + open rooms): could prompt injection turn into shell/file/network actions?
|
||||
- **Network exposure** (Gateway bind/auth, Tailscale Serve/Funnel).
|
||||
- **Browser control exposure** (remote controlUrl without token, HTTP, token reuse).
|
||||
- **Browser control exposure** (remote nodes, relay ports, remote CDP endpoints).
|
||||
- **Local disk hygiene** (permissions, symlinks, config includes, “synced folder” paths).
|
||||
- **Plugins** (extensions exist without an explicit allowlist).
|
||||
- **Model hygiene** (warn when configured models look legacy; not a hard block).
|
||||
@@ -61,7 +63,7 @@ When the audit prints findings, treat this as a priority order:
|
||||
|
||||
1. **Anything “open” + tools enabled**: lock down DMs/groups first (pairing/allowlists), then tighten tool policy/sandboxing.
|
||||
2. **Public network exposure** (LAN bind, Funnel, missing auth): fix immediately.
|
||||
3. **Browser control remote exposure**: treat it like a remote admin API (token required; HTTPS/tailnet-only).
|
||||
3. **Browser control remote exposure**: treat it like operator access (tailnet-only, pair nodes deliberately, avoid public exposure).
|
||||
4. **Permissions**: make sure state/config/credentials/auth are not group/world-readable.
|
||||
5. **Plugins/extensions**: only load what you explicitly trust.
|
||||
6. **Model choice**: prefer modern, instruction-hardened models for any bot with tools.
|
||||
@@ -142,6 +144,16 @@ Clawdbot’s stance:
|
||||
- **Scope next:** decide where the bot is allowed to act (group allowlists + mention gating, tools, sandboxing, device permissions).
|
||||
- **Model last:** assume the model can be manipulated; design so manipulation has limited blast radius.
|
||||
|
||||
## Command authorization model
|
||||
|
||||
Slash commands and directives are only honored for **authorized senders**. Authorization is derived from
|
||||
channel allowlists/pairing plus `commands.useAccessGroups` (see [Configuration](/gateway/configuration)
|
||||
and [Slash commands](/tools/slash-commands)). If a channel allowlist is empty or includes `"*"`,
|
||||
commands are effectively open for that channel.
|
||||
|
||||
`/exec` is a session-only convenience for authorized operators. It does **not** write config or
|
||||
change other sessions.
|
||||
|
||||
## Plugins/extensions
|
||||
|
||||
Plugins run **in-process** with the Gateway. Treat them as trusted code:
|
||||
@@ -267,7 +279,7 @@ Assume “compromised” means: someone got into a room that can trigger the bot
|
||||
- Lock down inbound surfaces (DM policy, group allowlists, mention gating).
|
||||
2. **Rotate secrets**
|
||||
- Rotate `gateway.auth` token/password.
|
||||
- Rotate `browser.controlToken` and `hooks.token` (if used).
|
||||
- Rotate `hooks.token` (if used) and revoke any suspicious node pairings.
|
||||
- Revoke/rotate model provider credentials (API keys / OAuth).
|
||||
3. **Review artifacts**
|
||||
- Check Gateway logs and recent sessions/transcripts for unexpected tool calls.
|
||||
@@ -420,26 +432,19 @@ Trusted proxies:
|
||||
|
||||
See [Tailscale](/gateway/tailscale) and [Web overview](/web).
|
||||
|
||||
### 0.6.1) Browser control server over Tailscale (recommended)
|
||||
### 0.6.1) Browser control via node host (recommended)
|
||||
|
||||
If your Gateway is remote but the browser runs on another machine, you’ll often run a **separate browser control server**
|
||||
on the browser machine (see [Browser tool](/tools/browser)). Treat this like an admin API.
|
||||
If your Gateway is remote but the browser runs on another machine, run a **node host**
|
||||
on the browser machine and let the Gateway proxy browser actions (see [Browser tool](/tools/browser)).
|
||||
Treat node pairing like admin access.
|
||||
|
||||
Recommended pattern:
|
||||
|
||||
```bash
|
||||
# on the machine that runs Chrome
|
||||
clawdbot browser serve --bind 127.0.0.1 --port 18791 --token <token>
|
||||
tailscale serve https / http://127.0.0.1:18791
|
||||
```
|
||||
|
||||
Then on the Gateway, set:
|
||||
- `browser.controlUrl` to the `https://…` Serve URL (MagicDNS/ts.net)
|
||||
- and authenticate with the same token (`CLAWDBOT_BROWSER_CONTROL_TOKEN` env preferred)
|
||||
- Keep the Gateway and node host on the same tailnet (Tailscale).
|
||||
- Pair the node intentionally; disable browser proxy routing if you don’t need it.
|
||||
|
||||
Avoid:
|
||||
- `--bind 0.0.0.0` (LAN-visible surface)
|
||||
- Tailscale Funnel for browser control endpoints (public exposure)
|
||||
- Exposing relay/control ports over LAN or public Internet.
|
||||
- Tailscale Funnel for browser control endpoints (public exposure).
|
||||
|
||||
### 0.7) Secrets on disk (what’s sensitive)
|
||||
|
||||
@@ -567,13 +572,15 @@ If that browser profile already contains logged-in sessions, the model can
|
||||
access those accounts and data. Treat browser profiles as **sensitive state**:
|
||||
- Prefer a dedicated profile for the agent (the default `clawd` profile).
|
||||
- Avoid pointing the agent at your personal daily-driver profile.
|
||||
- `act:evaluate` and `wait --fn` run arbitrary JavaScript in the page context.
|
||||
Prompt injection can steer the model into calling them. If you do not need
|
||||
them, set `browser.evaluateEnabled=false` (see [Configuration](/gateway/configuration#browser-clawd-managed-browser)).
|
||||
- Keep host browser control disabled for sandboxed agents unless you trust them.
|
||||
- Treat browser downloads as untrusted input; prefer an isolated downloads directory.
|
||||
- Disable browser sync/password managers in the agent profile if possible (reduces blast radius).
|
||||
- For remote gateways, assume “browser control” is equivalent to “operator access” to whatever that profile can reach.
|
||||
- Treat `browser.controlUrl` endpoints as an admin API: tailnet-only + token auth. Prefer Tailscale Serve over LAN binds.
|
||||
- Keep `browser.controlToken` separate from `gateway.auth.token` (you can reuse it, but that increases blast radius).
|
||||
- Prefer env vars for the token (`CLAWDBOT_BROWSER_CONTROL_TOKEN`) instead of storing it in config on disk.
|
||||
- Keep the Gateway and node hosts tailnet-only; avoid exposing relay/control ports to LAN or public Internet.
|
||||
- Disable browser proxy routing when you don’t need it (`gateway.nodes.browser.mode="off"`).
|
||||
- Chrome extension relay mode is **not** “safer”; it can take over your existing Chrome tabs. Assume it can act as you in whatever that tab/profile can reach.
|
||||
|
||||
## Per-agent access profiles (multi-agent)
|
||||
|
||||
@@ -100,35 +100,13 @@ clawdbot gateway --tailscale funnel --auth password
|
||||
- Serve/Funnel only expose the **Gateway control UI + WS**. Nodes connect over
|
||||
the same Gateway WS endpoint, so Serve can work for node access.
|
||||
|
||||
## Browser control server (remote Gateway + local browser)
|
||||
## Browser control (remote Gateway + local browser)
|
||||
|
||||
If you run the Gateway on one machine but want to drive a browser on another machine, use a **separate browser control server**
|
||||
and publish it through Tailscale **Serve** (tailnet-only):
|
||||
If you run the Gateway on one machine but want to drive a browser on another machine,
|
||||
run a **node host** on the browser machine and keep both on the same tailnet.
|
||||
The Gateway will proxy browser actions to the node; no separate control server or Serve URL needed.
|
||||
|
||||
```bash
|
||||
# on the machine that runs Chrome
|
||||
clawdbot browser serve --bind 127.0.0.1 --port 18791 --token <token>
|
||||
tailscale serve https / http://127.0.0.1:18791
|
||||
```
|
||||
|
||||
Then point the Gateway config at the HTTPS URL:
|
||||
|
||||
```json5
|
||||
{
|
||||
browser: {
|
||||
enabled: true,
|
||||
controlUrl: "https://<magicdns>/"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
And authenticate from the Gateway with the same token (prefer env):
|
||||
|
||||
```bash
|
||||
export CLAWDBOT_BROWSER_CONTROL_TOKEN="<token>"
|
||||
```
|
||||
|
||||
Avoid Funnel for browser control endpoints unless you explicitly want public exposure.
|
||||
Avoid Funnel for browser control; treat node pairing like operator access.
|
||||
|
||||
## Tailscale prerequisites + limits
|
||||
|
||||
|
||||
+4
-3
@@ -1093,9 +1093,10 @@ clawdbot browser extension path
|
||||
|
||||
Then Chrome → `chrome://extensions` → enable “Developer mode” → “Load unpacked” → pick that folder.
|
||||
|
||||
Full guide (including remote Gateway via Tailscale + security notes): [Chrome extension](/tools/chrome-extension)
|
||||
Full guide (including remote Gateway + security notes): [Chrome extension](/tools/chrome-extension)
|
||||
|
||||
If the Gateway runs on the same machine as Chrome (default setup), you usually **do not** need `clawdbot browser serve`.
|
||||
If the Gateway runs on the same machine as Chrome (default setup), you usually **do not** need anything extra.
|
||||
If the Gateway runs elsewhere, run a node host on the browser machine so the Gateway can proxy browser actions.
|
||||
You still need to click the extension button on the tab you want to control (it doesn’t auto-attach).
|
||||
|
||||
## Sandboxing and memory
|
||||
@@ -1479,7 +1480,7 @@ setup is an always‑on host plus your laptop as a node.
|
||||
- **Safer execution controls.** `system.run` is gated by node allowlists/approvals on that laptop.
|
||||
- **More device tools.** Nodes expose `canvas`, `camera`, and `screen` in addition to `system.run`.
|
||||
- **Local browser automation.** Keep the Gateway on a VPS, but run Chrome locally and relay control
|
||||
with the Chrome extension + `clawdbot browser serve`.
|
||||
with the Chrome extension + a node host on the laptop.
|
||||
|
||||
SSH is fine for ad‑hoc shell access, but nodes are simpler for ongoing agent workflows and
|
||||
device automation.
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
---
|
||||
title: "Node.js + npm (PATH sanity)"
|
||||
summary: "Node.js + npm install sanity: versions, PATH, and global installs"
|
||||
read_when:
|
||||
- You installed Clawdbot but `clawdbot` is “command not found”
|
||||
- You’re setting up Node.js/npm on a new machine
|
||||
- `npm install -g ...` fails with permissions or PATH issues
|
||||
- "You installed Clawdbot but `clawdbot` is “command not found”"
|
||||
- "You’re setting up Node.js/npm on a new machine"
|
||||
- "npm install -g ... fails with permissions or PATH issues"
|
||||
---
|
||||
|
||||
# Node.js + npm (PATH sanity)
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
title: Deploy on Northflank
|
||||
---
|
||||
|
||||
Deploy Clawdbot on Northflank with a one-click template and finish setup in your browser.
|
||||
This is the easiest “no terminal on the server” path: Northflank runs the Gateway for you,
|
||||
and you configure everything via the `/setup` web wizard.
|
||||
|
||||
## How to get started
|
||||
|
||||
1. Click [Deploy Clawdbot](https://northflank.com/stacks/deploy-clawdbot) to open the template.
|
||||
2. Create an [account on Northflank](https://app.northflank.com/signup) if you don’t already have one.
|
||||
3. Click **Deploy Clawdbot now**.
|
||||
4. Set the required environment variable: `SETUP_PASSWORD`.
|
||||
5. Click **Deploy stack** to build and run the Clawdbot template.
|
||||
6. Wait for the deployment to complete, then click **View resources**.
|
||||
7. Open the Clawdbot service.
|
||||
8. Open the public Clawdbot URL and complete setup at `/setup`.
|
||||
9. Open the Control UI at `/clawdbot`.
|
||||
|
||||
## What you get
|
||||
|
||||
- Hosted Clawdbot Gateway + Control UI
|
||||
- Web setup wizard at `/setup` (no terminal commands)
|
||||
- Persistent storage via Northflank Volume (`/data`) so config/credentials/workspace survive redeploys
|
||||
|
||||
## Setup flow
|
||||
|
||||
1) Visit `https://<your-northflank-domain>/setup` and enter your `SETUP_PASSWORD`.
|
||||
2) Choose a model/auth provider and paste your key.
|
||||
3) (Optional) Add Telegram/Discord/Slack tokens.
|
||||
4) Click **Run setup**.
|
||||
5) Open the Control UI at `https://<your-northflank-domain>/clawdbot`
|
||||
|
||||
If Telegram DMs are set to pairing, the setup wizard can approve the pairing code.
|
||||
|
||||
## Getting chat tokens
|
||||
|
||||
### Telegram bot token
|
||||
|
||||
1) Message `@BotFather` in Telegram
|
||||
2) Run `/newbot`
|
||||
3) Copy the token (looks like `123456789:AA...`)
|
||||
4) Paste it into `/setup`
|
||||
|
||||
### Discord bot token
|
||||
|
||||
1) Go to https://discord.com/developers/applications
|
||||
2) **New Application** → choose a name
|
||||
3) **Bot** → **Add Bot**
|
||||
4) **Enable MESSAGE CONTENT INTENT** under Bot → Privileged Gateway Intents (required or the bot will crash on startup)
|
||||
5) Copy the **Bot Token** and paste into `/setup`
|
||||
6) Invite the bot to your server (OAuth2 URL Generator; scopes: `bot`, `applications.commands`)
|
||||
@@ -104,6 +104,7 @@ Notes:
|
||||
- `mock` is a local dev provider (no network calls).
|
||||
- `skipSignatureVerification` is for local testing only.
|
||||
- If you use ngrok free tier, set `publicUrl` to the exact ngrok URL; signature verification is always enforced.
|
||||
- `tunnel.allowNgrokFreeTierLoopbackBypass: true` allows Twilio webhooks with invalid signatures **only** when `tunnel.provider="ngrok"` and `serve.bind` is loopback (ngrok local agent). Use for local dev only.
|
||||
- Ngrok free tier URLs can change or add interstitial behavior; if `publicUrl` drifts, Twilio signatures will fail. For production, prefer a stable domain or Tailscale funnel.
|
||||
|
||||
## TTS for calls
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
---
|
||||
title: Formal Verification (Security Models)
|
||||
summary: Machine-checked security models for Clawdbot’s highest-risk paths.
|
||||
permalink: /security/formal-verification/
|
||||
---
|
||||
|
||||
# Formal Verification (Security Models)
|
||||
|
||||
This page tracks Clawdbot’s **formal security models** (TLA+/TLC today; more as needed).
|
||||
|
||||
**Goal (north star):** provide a machine-checked argument that Clawdbot enforces its
|
||||
intended security policy (authorization, session isolation, tool gating, and
|
||||
misconfiguration safety), under explicit assumptions.
|
||||
|
||||
**What this is (today):** an executable, attacker-driven **security regression suite**:
|
||||
- Each claim has a runnable model-check over a finite state space.
|
||||
- Many claims have a paired **negative model** that produces a counterexample trace for a realistic bug class.
|
||||
|
||||
**What this is not (yet):** a proof that “Clawdbot is secure in all respects” or that the full TypeScript implementation is correct.
|
||||
|
||||
## Where the models live
|
||||
|
||||
Models are maintained in a separate repo: [vignesh07/clawdbot-formal-models](https://github.com/vignesh07/clawdbot-formal-models).
|
||||
|
||||
## Important caveats
|
||||
|
||||
- These are **models**, not the full TypeScript implementation. Drift between model and code is possible.
|
||||
- Results are bounded by the state space explored by TLC; “green” does not imply security beyond the modeled assumptions and bounds.
|
||||
- Some claims rely on explicit environmental assumptions (e.g., correct deployment, correct configuration inputs).
|
||||
|
||||
## Reproducing results
|
||||
|
||||
Today, results are reproduced by cloning the models repo locally and running TLC (see below). A future iteration could offer:
|
||||
- CI-run models with public artifacts (counterexample traces, run logs)
|
||||
- a hosted “run this model” workflow for small, bounded checks
|
||||
|
||||
Getting started:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/vignesh07/clawdbot-formal-models
|
||||
cd clawdbot-formal-models
|
||||
|
||||
# Java 11+ required (TLC runs on the JVM).
|
||||
# The repo vendors a pinned `tla2tools.jar` (TLA+ tools) and provides `bin/tlc` + Make targets.
|
||||
|
||||
make <target>
|
||||
```
|
||||
|
||||
### Gateway exposure and open gateway misconfiguration
|
||||
|
||||
**Claim:** binding beyond loopback without auth can make remote compromise possible / increases exposure; token/password blocks unauth attackers (per the model assumptions).
|
||||
|
||||
- Green runs:
|
||||
- `make gateway-exposure-v2`
|
||||
- `make gateway-exposure-v2-protected`
|
||||
- Red (expected):
|
||||
- `make gateway-exposure-v2-negative`
|
||||
|
||||
See also: `docs/gateway-exposure-matrix.md` in the models repo.
|
||||
|
||||
### Nodes.run pipeline (highest-risk capability)
|
||||
|
||||
**Claim:** `nodes.run` requires (a) node command allowlist plus declared commands and (b) live approval when configured; approvals are tokenized to prevent replay (in the model).
|
||||
|
||||
- Green runs:
|
||||
- `make nodes-pipeline`
|
||||
- `make approvals-token`
|
||||
- Red (expected):
|
||||
- `make nodes-pipeline-negative`
|
||||
- `make approvals-token-negative`
|
||||
|
||||
### Pairing store (DM gating)
|
||||
|
||||
**Claim:** pairing requests respect TTL and pending-request caps.
|
||||
|
||||
- Green runs:
|
||||
- `make pairing`
|
||||
- `make pairing-cap`
|
||||
- Red (expected):
|
||||
- `make pairing-negative`
|
||||
- `make pairing-cap-negative`
|
||||
|
||||
### Ingress gating (mentions + control-command bypass)
|
||||
|
||||
**Claim:** in group contexts requiring mention, an unauthorized “control command” cannot bypass mention gating.
|
||||
|
||||
- Green:
|
||||
- `make ingress-gating`
|
||||
- Red (expected):
|
||||
- `make ingress-gating-negative`
|
||||
|
||||
### Routing/session-key isolation
|
||||
|
||||
**Claim:** DMs from distinct peers do not collapse into the same session unless explicitly linked/configured.
|
||||
|
||||
- Green:
|
||||
- `make routing-isolation`
|
||||
- Red (expected):
|
||||
- `make routing-isolation-negative`
|
||||
|
||||
## Roadmap
|
||||
|
||||
Next models to deepen fidelity:
|
||||
- Pairing store concurrency/locking/idempotency
|
||||
- Provider-specific ingress preflight modeling
|
||||
- Routing identity-links + dmScope variants + binding precedence
|
||||
- Gateway auth conformance (proxy/tailscale specifics)
|
||||
@@ -175,6 +175,7 @@ clawdbot onboard --install-daemon
|
||||
```
|
||||
|
||||
If you don’t have a global install yet, run the onboarding step via `pnpm clawdbot ...` from the repo.
|
||||
`pnpm build` also bundles A2UI assets; if you need to run just that step, use `pnpm canvas:a2ui:bundle`.
|
||||
|
||||
Gateway (from this repo):
|
||||
|
||||
|
||||
+29
-135
@@ -1,5 +1,5 @@
|
||||
---
|
||||
summary: "Integrated browser control server + action commands"
|
||||
summary: "Integrated browser control service + action commands"
|
||||
read_when:
|
||||
- Adding agent-controlled browser automation
|
||||
- Debugging why clawd is interfering with your own Chrome
|
||||
@@ -10,7 +10,7 @@ read_when:
|
||||
|
||||
Clawdbot can run a **dedicated Chrome/Brave/Edge/Chromium profile** that the agent controls.
|
||||
It is isolated from your personal browser and is managed through a small local
|
||||
control server.
|
||||
control service inside the Gateway (loopback only).
|
||||
|
||||
Beginner view:
|
||||
- Think of it as a **separate, agent-only browser**.
|
||||
@@ -57,8 +57,7 @@ Browser settings live in `~/.clawdbot/clawdbot.json`.
|
||||
{
|
||||
browser: {
|
||||
enabled: true, // default: true
|
||||
controlUrl: "http://127.0.0.1:18791",
|
||||
cdpUrl: "http://127.0.0.1:18792", // defaults to controlUrl + 1
|
||||
// cdpUrl: "http://127.0.0.1:18792", // legacy single-profile override
|
||||
remoteCdpTimeoutMs: 1500, // remote CDP HTTP timeout (ms)
|
||||
remoteCdpHandshakeTimeoutMs: 3000, // remote CDP WebSocket handshake timeout (ms)
|
||||
defaultProfile: "chrome",
|
||||
@@ -77,10 +76,11 @@ Browser settings live in `~/.clawdbot/clawdbot.json`.
|
||||
```
|
||||
|
||||
Notes:
|
||||
- `controlUrl` defaults to `http://127.0.0.1:18791`.
|
||||
- The browser control service binds to loopback on a port derived from `gateway.port`
|
||||
(default: `18791`, which is gateway + 2). The relay uses the next port (`18792`).
|
||||
- If you override the Gateway port (`gateway.port` or `CLAWDBOT_GATEWAY_PORT`),
|
||||
the default browser ports shift to stay in the same “family” (control = gateway + 2).
|
||||
- `cdpUrl` defaults to `controlUrl + 1` when unset.
|
||||
the derived browser ports shift to stay in the same “family”.
|
||||
- `cdpUrl` defaults to the relay port when unset.
|
||||
- `remoteCdpTimeoutMs` applies to remote (non-loopback) CDP reachability checks.
|
||||
- `remoteCdpHandshakeTimeoutMs` applies to remote CDP WebSocket reachability checks.
|
||||
- `attachOnly: true` means “never launch a local browser; only attach if it is already running.”
|
||||
@@ -126,38 +126,11 @@ clawdbot config set browser.executablePath "/usr/bin/google-chrome"
|
||||
|
||||
## Local vs remote control
|
||||
|
||||
- **Local control (default):** `controlUrl` is loopback (`127.0.0.1`/`localhost`).
|
||||
The Gateway starts the control server and can launch a local browser.
|
||||
- **Remote control:** `controlUrl` is non-loopback. The Gateway **does not** start
|
||||
a local server; it assumes you are pointing at an existing server elsewhere.
|
||||
- **Local control (default):** the Gateway starts the loopback control service and can launch a local browser.
|
||||
- **Remote control (node host):** run a node host on the machine that has the browser; the Gateway proxies browser actions to it.
|
||||
- **Remote CDP:** set `browser.profiles.<name>.cdpUrl` (or `browser.cdpUrl`) to
|
||||
attach to a remote Chromium-based browser. In this case, Clawdbot will not launch a local browser.
|
||||
|
||||
## Remote browser (control server)
|
||||
|
||||
You can run the **browser control server** on another machine and point your
|
||||
Gateway at it with a remote `controlUrl`. This lets the agent drive a browser
|
||||
outside the host (lab box, VM, remote desktop, etc.).
|
||||
|
||||
Key points:
|
||||
- The **control server** speaks to Chromium-based browsers (Chrome/Brave/Edge/Chromium) via **CDP**.
|
||||
- The **Gateway** only needs the HTTP control URL.
|
||||
- Profiles are resolved on the **control server** side.
|
||||
|
||||
Example:
|
||||
```json5
|
||||
{
|
||||
browser: {
|
||||
enabled: true,
|
||||
controlUrl: "http://10.0.0.42:18791",
|
||||
defaultProfile: "work"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Use `profiles.<name>.cdpUrl` for **remote CDP** if you want the Gateway to talk
|
||||
directly to a Chromium-based browser instance without a remote control server.
|
||||
|
||||
Remote CDP URLs can include auth:
|
||||
- Query tokens (e.g., `https://provider.example?token=<token>`)
|
||||
- HTTP Basic auth (e.g., `https://user:pass@provider.example`)
|
||||
@@ -166,11 +139,11 @@ Clawdbot preserves the auth when calling `/json/*` endpoints and when connecting
|
||||
to the CDP WebSocket. Prefer environment variables or secrets managers for
|
||||
tokens instead of committing them to config files.
|
||||
|
||||
### Node browser proxy (zero-config default)
|
||||
## Node browser proxy (zero-config default)
|
||||
|
||||
If you run a **node host** on the machine that has your browser, Clawdbot can
|
||||
auto-route browser tool calls to that node without any custom `controlUrl`
|
||||
setup. This is the default path for remote gateways.
|
||||
auto-route browser tool calls to that node without any extra browser config.
|
||||
This is the default path for remote gateways.
|
||||
|
||||
Notes:
|
||||
- The node host exposes its local browser control server via a **proxy command**.
|
||||
@@ -179,7 +152,7 @@ Notes:
|
||||
- On the node: `nodeHost.browserProxy.enabled=false`
|
||||
- On the gateway: `gateway.nodes.browser.mode="off"`
|
||||
|
||||
### Browserless (hosted remote CDP)
|
||||
## Browserless (hosted remote CDP)
|
||||
|
||||
[Browserless](https://browserless.io) is a hosted Chromium service that exposes
|
||||
CDP endpoints over HTTPS. You can point a Clawdbot browser profile at a
|
||||
@@ -207,94 +180,16 @@ Notes:
|
||||
- Replace `<BROWSERLESS_API_KEY>` with your real Browserless token.
|
||||
- Choose the region endpoint that matches your Browserless account (see their docs).
|
||||
|
||||
### Running the control server on the browser machine
|
||||
|
||||
Run a standalone browser control server (recommended when your Gateway is remote):
|
||||
|
||||
```bash
|
||||
# on the machine that runs Chrome/Brave/Edge
|
||||
clawdbot browser serve --bind <browser-host> --port 18791 --token <token>
|
||||
```
|
||||
|
||||
Then point your Gateway at it:
|
||||
|
||||
```json5
|
||||
{
|
||||
browser: {
|
||||
enabled: true,
|
||||
controlUrl: "http://<browser-host>:18791",
|
||||
|
||||
// Option A (recommended): keep token in env on the Gateway
|
||||
// (avoid writing secrets into config files)
|
||||
// controlToken: "<token>"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
And set the auth token in the Gateway environment:
|
||||
|
||||
```bash
|
||||
export CLAWDBOT_BROWSER_CONTROL_TOKEN="<token>"
|
||||
```
|
||||
|
||||
Option B: store the token in the Gateway config instead (same shared token):
|
||||
|
||||
```json5
|
||||
{
|
||||
browser: {
|
||||
enabled: true,
|
||||
controlUrl: "http://<browser-host>:18791",
|
||||
controlToken: "<token>"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Security
|
||||
|
||||
This section covers the **browser control server** (`browser.controlUrl`) used for agent browser automation.
|
||||
|
||||
Key ideas:
|
||||
- Treat the browser control server like an admin API: **private network only**.
|
||||
- Use **token auth** always when the server is reachable off-machine.
|
||||
- Prefer **Tailnet-only** connectivity over LAN exposure.
|
||||
- Browser control is loopback-only; access flows through the Gateway’s auth or node pairing.
|
||||
- Keep the Gateway and any node hosts on a private network (Tailscale); avoid public exposure.
|
||||
- Treat remote CDP URLs/tokens as secrets; prefer env vars or a secrets manager.
|
||||
|
||||
### Tokens (what is shared with what?)
|
||||
|
||||
- `browser.controlToken` / `CLAWDBOT_BROWSER_CONTROL_TOKEN` is **only** for authenticating browser control HTTP requests to `browser.controlUrl`.
|
||||
- It is **not** the Gateway token (`gateway.auth.token`) and **not** a node pairing token.
|
||||
- You *can* reuse the same string value, but it’s better to keep them separate to reduce blast radius.
|
||||
|
||||
### Binding (don’t expose to your LAN by accident)
|
||||
|
||||
Recommended:
|
||||
- Keep `clawdbot browser serve` bound to loopback (`127.0.0.1`) and publish it via Tailscale.
|
||||
- Or bind to a Tailnet IP only (never `0.0.0.0`) and require a token.
|
||||
|
||||
Avoid:
|
||||
- `--bind 0.0.0.0` (LAN-visible). Even with token auth, traffic is plain HTTP unless you also add TLS.
|
||||
|
||||
### TLS / HTTPS (recommended approach: terminate in front)
|
||||
|
||||
Best practice here: keep `clawdbot browser serve` on HTTP and terminate TLS in front.
|
||||
|
||||
If you’re already using Tailscale, you have two good options:
|
||||
|
||||
1) **Tailnet-only, still HTTP** (transport is encrypted by Tailscale):
|
||||
- Keep `controlUrl` as `http://…` but ensure it’s only reachable over your tailnet.
|
||||
|
||||
2) **Serve HTTPS via Tailscale** (nice UX: `https://…` URL):
|
||||
|
||||
```bash
|
||||
# on the browser machine
|
||||
clawdbot browser serve --bind 127.0.0.1 --port 18791 --token <token>
|
||||
tailscale serve https / http://127.0.0.1:18791
|
||||
```
|
||||
|
||||
Then set your Gateway config `browser.controlUrl` to the HTTPS URL (MagicDNS/ts.net) and keep using the same token.
|
||||
|
||||
Notes:
|
||||
- Do **not** use Tailscale Funnel for this unless you explicitly want to make the endpoint public.
|
||||
- For Tailnet setup/background, see [Gateway web surfaces](/web/index) and the [Gateway CLI](/cli/gateway).
|
||||
Remote CDP tips:
|
||||
- Prefer HTTPS endpoints and short-lived tokens where possible.
|
||||
- Avoid embedding long-lived tokens directly in config files.
|
||||
|
||||
## Profiles (multi-browser)
|
||||
|
||||
@@ -318,13 +213,12 @@ Clawdbot can also drive **your existing Chrome tabs** (no separate “clawd” C
|
||||
Full guide: [Chrome extension](/tools/chrome-extension)
|
||||
|
||||
Flow:
|
||||
- You run a **browser control server** (Gateway on the same machine, or `clawdbot browser serve`).
|
||||
- The Gateway runs locally (same machine) or a node host runs on the browser machine.
|
||||
- A local **relay server** listens at a loopback `cdpUrl` (default: `http://127.0.0.1:18792`).
|
||||
- You click the **Clawdbot Browser Relay** extension icon on a tab to attach (it does not auto-attach).
|
||||
- The agent controls that tab via the normal `browser` tool, by selecting the right profile.
|
||||
|
||||
If the Gateway runs on the same machine as Chrome (default setup), you usually **do not** need `clawdbot browser serve`.
|
||||
Use `browser serve` only when the Gateway runs elsewhere (remote mode).
|
||||
If the Gateway runs elsewhere, run a node host on the browser machine so the Gateway can proxy browser actions.
|
||||
|
||||
### Sandboxed sessions
|
||||
|
||||
@@ -387,8 +281,7 @@ Platforms:
|
||||
|
||||
## Control API (optional)
|
||||
|
||||
If you want to integrate directly, the browser control server exposes a small
|
||||
HTTP API:
|
||||
For local integrations only, the Gateway exposes a small loopback HTTP API:
|
||||
|
||||
- Status/start/stop: `GET /`, `POST /start`, `POST /stop`
|
||||
- Tabs: `GET /tabs`, `POST /tabs/open`, `POST /tabs/focus`, `DELETE /tabs/:targetId`
|
||||
@@ -612,8 +505,11 @@ These are useful for “make the site behave like X” workflows:
|
||||
## Security & privacy
|
||||
|
||||
- The clawd browser profile may contain logged-in sessions; treat it as sensitive.
|
||||
- `browser act kind=evaluate` / `clawdbot browser evaluate` and `wait --fn`
|
||||
execute arbitrary JavaScript in the page context. Prompt injection can steer
|
||||
this. Disable it with `browser.evaluateEnabled=false` if you do not need it.
|
||||
- For logins and anti-bot notes (X/Twitter, etc.), see [Browser login + X/Twitter posting](/tools/browser-login).
|
||||
- Keep control URLs loopback-only unless you intentionally expose the server.
|
||||
- Keep the Gateway/node host private (loopback or tailnet-only).
|
||||
- Remote CDP endpoints are powerful; tunnel and protect them.
|
||||
|
||||
## Troubleshooting
|
||||
@@ -631,12 +527,10 @@ How it maps:
|
||||
- `browser act` uses the snapshot `ref` IDs to click/type/drag/select.
|
||||
- `browser screenshot` captures pixels (full page or element).
|
||||
- `browser` accepts:
|
||||
- `profile` to choose a named browser profile (host or remote control server).
|
||||
- `target` (`sandbox` | `host` | `custom`) to select where the browser lives.
|
||||
- `controlUrl` sets `target: "custom"` implicitly (remote control server).
|
||||
- `profile` to choose a named browser profile (clawd, chrome, or remote CDP).
|
||||
- `target` (`sandbox` | `host` | `node`) to select where the browser lives.
|
||||
- In sandboxed sessions, `target: "host"` requires `agents.defaults.sandbox.browser.allowHostControl=true`.
|
||||
- If `target` is omitted: sandboxed sessions default to `sandbox`, non-sandbox sessions default to `host`.
|
||||
- Sandbox allowlists can restrict `target: "custom"` to specific URLs/hosts/ports.
|
||||
- Defaults: allowlists unset (no restriction), and sandbox host control is disabled.
|
||||
- If a browser-capable node is connected, the tool may auto-route to it unless you pin `target="host"` or `target="node"`.
|
||||
|
||||
This keeps the agent deterministic and avoids brittle selectors.
|
||||
@@ -15,7 +15,7 @@ Attach/detach happens via a **single Chrome toolbar button**.
|
||||
## What it is (concept)
|
||||
|
||||
There are three parts:
|
||||
- **Browser control server** (HTTP): the API the agent/tool calls (`browser.controlUrl`)
|
||||
- **Browser control service** (Gateway or node): the API the agent/tool calls (via the Gateway)
|
||||
- **Local relay server** (loopback CDP): bridges between the control server and the extension (`http://127.0.0.1:18792` by default)
|
||||
- **Chrome MV3 extension**: attaches to the active tab using `chrome.debugger` and pipes CDP messages to the relay
|
||||
|
||||
@@ -87,23 +87,22 @@ clawdbot browser create-profile \
|
||||
- `!`: relay not reachable (most common: browser relay server isn’t running on this machine).
|
||||
|
||||
If you see `!`:
|
||||
- Make sure the Gateway is running locally (default setup), or run `clawdbot browser serve` on this machine (remote gateway setup).
|
||||
- Make sure the Gateway is running locally (default setup), or run a node host on this machine if the Gateway runs elsewhere.
|
||||
- Open the extension Options page; it shows whether the relay is reachable.
|
||||
|
||||
## Do I need `clawdbot browser serve`?
|
||||
## Remote Gateway (use a node host)
|
||||
|
||||
### Local Gateway (same machine as Chrome) — usually **no**
|
||||
### Local Gateway (same machine as Chrome) — usually **no extra steps**
|
||||
|
||||
If the Gateway is running on the same machine as Chrome and your `browser.controlUrl` is loopback (default),
|
||||
you typically **do not** need `clawdbot browser serve`.
|
||||
If the Gateway runs on the same machine as Chrome, it starts the browser control service on loopback
|
||||
and auto-starts the relay server. The extension talks to the local relay; the CLI/tool calls go to the Gateway.
|
||||
|
||||
The Gateway’s built-in browser control server will start on `http://127.0.0.1:18791/` and Clawdbot will
|
||||
auto-start the local relay server on `http://127.0.0.1:18792/`.
|
||||
### Remote Gateway (Gateway runs elsewhere) — **run a node host**
|
||||
|
||||
### Remote Gateway (Gateway runs elsewhere) — **yes**
|
||||
If your Gateway runs on another machine, start a node host on the machine that runs Chrome.
|
||||
The Gateway will proxy browser actions to that node; the extension + relay stay local to the browser machine.
|
||||
|
||||
If your Gateway runs on another machine, run `clawdbot browser serve` on the machine that runs Chrome
|
||||
(and publish it via Tailscale Serve / TLS). See the section below.
|
||||
If multiple nodes are connected, pin one with `gateway.nodes.browser.node` or set `gateway.nodes.browser.mode`.
|
||||
|
||||
## Sandboxing (tool containers)
|
||||
|
||||
@@ -134,26 +133,10 @@ Then ensure the tool isn’t denied by tool policy, and (if needed) call `browse
|
||||
|
||||
Debugging: `clawdbot sandbox explain`
|
||||
|
||||
## Remote Gateway (recommended: Tailscale Serve)
|
||||
## Remote access tips
|
||||
|
||||
Goal: Gateway runs on one machine, but Chrome runs somewhere else.
|
||||
|
||||
On the **browser machine**:
|
||||
|
||||
```bash
|
||||
clawdbot browser serve --bind 127.0.0.1 --port 18791 --token <token>
|
||||
tailscale serve https / http://127.0.0.1:18791
|
||||
```
|
||||
|
||||
On the **Gateway machine**:
|
||||
- Set `browser.controlUrl` to the HTTPS Serve URL (MagicDNS/ts.net).
|
||||
- Provide the token (prefer env):
|
||||
|
||||
```bash
|
||||
export CLAWDBOT_BROWSER_CONTROL_TOKEN="<token>"
|
||||
```
|
||||
|
||||
Then the agent can drive the browser by calling the remote `browser.controlUrl` API, while the extension + relay stay local on the browser machine.
|
||||
- Keep the Gateway and node host on the same tailnet; avoid exposing relay ports to LAN or public Internet.
|
||||
- Pair nodes intentionally; disable browser proxy routing if you don’t want remote control (`gateway.nodes.browser.mode="off"`).
|
||||
|
||||
## How “extension path” works
|
||||
|
||||
@@ -176,8 +159,8 @@ This is powerful and risky. Treat it like giving the model “hands on your brow
|
||||
|
||||
Recommendations:
|
||||
- Prefer a dedicated Chrome profile (separate from your personal browsing) for extension relay usage.
|
||||
- Keep the browser control server tailnet-only (Tailscale) and require a token.
|
||||
- Avoid exposing browser control over LAN (`0.0.0.0`) and avoid Funnel (public).
|
||||
- Keep the Gateway and any node hosts tailnet-only; rely on Gateway auth + node pairing.
|
||||
- Avoid exposing relay ports over LAN (`0.0.0.0`) and avoid Funnel (public).
|
||||
|
||||
Related:
|
||||
- Browser tool overview: [Browser](/tools/browser)
|
||||
|
||||
@@ -23,6 +23,7 @@ read_when:
|
||||
- **Approvals**: `full` skips exec approvals; `on`/`ask` honor them when allowlist/ask rules require.
|
||||
- **Unsandboxed agents**: no-op for location; only affects gating, logging, and status.
|
||||
- **Tool policy still applies**: if `exec` is denied by tool policy, elevated cannot be used.
|
||||
- **Separate from `/exec`**: `/exec` adjusts per-session defaults for authorized senders and does not require elevated.
|
||||
|
||||
## Resolution order
|
||||
1. Inline directive on the message (applies only to that message).
|
||||
|
||||
@@ -216,6 +216,9 @@ Approval-gated execs reuse the approval id as the `runId` in these messages for
|
||||
- **full** is powerful; prefer allowlists when possible.
|
||||
- **ask** keeps you in the loop while still allowing fast approvals.
|
||||
- Per-agent allowlists prevent one agent’s approvals from leaking into others.
|
||||
- Approvals only apply to host exec requests from **authorized senders**. Unauthorized senders cannot issue `/exec`.
|
||||
- `/exec security=full` is a session-level convenience for authorized operators and skips approvals by design.
|
||||
To hard-block host exec, set approvals security to `deny` or deny the `exec` tool via tool policy.
|
||||
|
||||
Related:
|
||||
- [Exec tool](/tools/exec)
|
||||
|
||||
+9
-1
@@ -67,7 +67,8 @@ Example:
|
||||
- macOS: `/opt/homebrew/bin`, `/usr/local/bin`, `/usr/bin`, `/bin`
|
||||
- Linux: `/usr/local/bin`, `/usr/bin`, `/bin`
|
||||
- `host=sandbox`: runs `sh -lc` (login shell) inside the container, so `/etc/profile` may reset `PATH`.
|
||||
Clawdbot prepends `env.PATH` after profile sourcing; `tools.exec.pathPrepend` applies here too.
|
||||
Clawdbot prepends `env.PATH` after profile sourcing via an internal env var (no shell interpolation);
|
||||
`tools.exec.pathPrepend` applies here too.
|
||||
- `host=node`: only env overrides you pass are sent to the node. `tools.exec.pathPrepend` only applies
|
||||
if the exec call already sets `env.PATH`. Headless node hosts accept `PATH` only when it prepends
|
||||
the node host PATH (no replacement). macOS nodes drop `PATH` overrides entirely.
|
||||
@@ -91,6 +92,13 @@ Example:
|
||||
/exec host=gateway security=allowlist ask=on-miss node=mac-1
|
||||
```
|
||||
|
||||
## Authorization model
|
||||
|
||||
`/exec` is only honored for **authorized senders** (channel allowlists/pairing plus `commands.useAccessGroups`).
|
||||
It updates **session state only** and does not write config. To hard-disable exec, deny it via tool
|
||||
policy (`tools.deny: ["exec"]` or per-agent). Host approvals still apply unless you explicitly set
|
||||
`security=full` and `ask=off`.
|
||||
|
||||
## Exec approvals (companion app / node host)
|
||||
|
||||
Sandboxed agents can require per-request approval before `exec` runs on the gateway or node host.
|
||||
|
||||
+6
-3
@@ -249,16 +249,17 @@ Profile management:
|
||||
- `reset-profile` — kill orphan process on profile's port (local only)
|
||||
|
||||
Common parameters:
|
||||
- `controlUrl` (defaults from config)
|
||||
- `profile` (optional; defaults to `browser.defaultProfile`)
|
||||
- `target` (`sandbox` | `host` | `node`)
|
||||
- `node` (optional; picks a specific node id/name)
|
||||
Notes:
|
||||
- Requires `browser.enabled=true` (default is `true`; set `false` to disable).
|
||||
- Uses `browser.controlUrl` unless `controlUrl` is passed explicitly.
|
||||
- All actions accept optional `profile` parameter for multi-instance support.
|
||||
- When `profile` is omitted, uses `browser.defaultProfile` (defaults to "chrome").
|
||||
- Profile names: lowercase alphanumeric + hyphens only (max 64 chars).
|
||||
- Port range: 18800-18899 (~100 profiles max).
|
||||
- Remote profiles are attach-only (no start/stop/reset).
|
||||
- If a browser-capable node is connected, the tool may auto-route to it (unless you pin `target`).
|
||||
- `snapshot` defaults to `ai` when Playwright is installed; use `aria` for the accessibility tree.
|
||||
- `snapshot` also supports role-snapshot options (`interactive`, `compact`, `depth`, `selector`) which return refs like `e12`.
|
||||
- `act` requires `ref` from `snapshot` (numeric `12` from AI snapshots, or `e12` from role snapshots); use `evaluate` for rare CSS selector needs.
|
||||
@@ -410,7 +411,9 @@ Gateway-backed tools (`canvas`, `nodes`, `cron`):
|
||||
- `timeoutMs`
|
||||
|
||||
Browser tool:
|
||||
- `controlUrl` (defaults from config)
|
||||
- `profile` (optional; defaults to `browser.defaultProfile`)
|
||||
- `target` (`sandbox` | `host` | `node`)
|
||||
- `node` (optional; pin a specific node id/name)
|
||||
|
||||
## Recommended agent flows
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ There are two related systems:
|
||||
- Directives are stripped from the message before the model sees it.
|
||||
- In normal chat messages (not directive-only), they are treated as “inline hints” and do **not** persist session settings.
|
||||
- In directive-only messages (the message contains only directives), they persist to the session and reply with an acknowledgement.
|
||||
- Directives are only applied for **authorized senders** (channel allowlists/pairing plus `commands.useAccessGroups`).
|
||||
Unauthorized senders see directives treated as plain text.
|
||||
|
||||
There are also a few **inline shortcuts** (allowlisted/authorized senders only): `/help`, `/commands`, `/status`, `/whoami` (`/id`).
|
||||
They run immediately, are stripped before the model sees the message, and the remaining text continues through the normal flow.
|
||||
|
||||
@@ -11,6 +11,8 @@ deployments work at a high level.
|
||||
|
||||
## Pick a provider
|
||||
|
||||
- **Railway** (one‑click + browser setup): [Railway](/railway)
|
||||
- **Northflank** (one‑click + browser setup): [Northflank](/northflank)
|
||||
- **Oracle Cloud (Always Free)**: [Oracle](/platforms/oracle) — $0/month (Always Free, ARM; capacity/signup can be finicky)
|
||||
- **Fly.io**: [Fly.io](/platforms/fly)
|
||||
- **Hetzner (Docker)**: [Hetzner](/platforms/hetzner)
|
||||
|
||||
Reference in new issue
Block a user