Skip to content

Commit d3de545

Browse files
wolfqingclaude
andcommitted
docs: describe the sandbox's home-directory rule and the sign-in window's lifecycle; retire Docker-only wording in comparison, always-on and FAQ
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1 parent 0647b10 commit d3de545

6 files changed

Lines changed: 46 additions & 14 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,31 @@ still change behaviour.
66

77
## [Unreleased]
88

9+
### Security
10+
11+
- A local computer's screen stream (`/screen/:botId/ws`) was served without the gateway's token and origin
12+
checks; it is now guarded like the noVNC path.
13+
- Sandboxed commands can no longer read the operator's home directory. Both sandboxes hide it entirely and put
14+
back only runtime managers (`~/.nvm`, `~/.volta`, `~/.pyenv`, `~/.cargo/bin`, …) read-only; before, Seatbelt
15+
denied a short list of key folders and bubblewrap denied none of them. The self-check now also fails if a
16+
command can list the home directory, and the switch refuses to turn on when no self-check is wired.
17+
- `write_file` on a local computer opens the final path component without following symlinks.
18+
19+
### Fixed
20+
21+
- The sign-in window of a local computer closed as soon as the teammate used its browser again, or a routine
22+
fired — while the operator might be typing a password. It now closes only when the operator speaks again
23+
(a message, a decision) or clicks *I'm done signing in*.
24+
- The panel's screen froze on the last frame after the browser was reopened for a sign-in; the stream now ends
25+
and the panel reconnects to the new browser.
26+
- The screen viewer no longer retries forever (relaunching the browser each time) after the gateway says there
27+
is no screen, and stops streaming while the tab is hidden.
28+
- The commands switch and the done button lock while the gateway works and show its refusal inline.
29+
- The shell tool and the briefing describe a local computer's working directory honestly (the folder is the
30+
working directory and `$HOME`; `/workspace` is the file tools' name for it); `ask_for_login` tells the model to
31+
stop and wait. The node the gateway runs on is first on a sandboxed command's PATH, so nvm-installed nodes work.
32+
- `running()` no longer counts a local computer whose browser the operator quit by hand.
33+
934
### Changed
1035

1136
- The READMEs describe local computers wherever they still assumed Docker: the FAQ no longer says Docker is

‎docs/always-on.md‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ a service: one process, one port, started at boot, reachable from your other mac
88
```bash
99
pnpm install
1010
pnpm build # web UI → web/dist, gateway → gateway/dist
11-
docker build -t opengrokbot/bot:dev docker/bot
11+
docker build -t opengrokbot/bot:dev docker/bot # only if the teammates use Docker computers
1212
OPENGROKBOT_API_KEY=sk-… pnpm start
1313
```
1414

@@ -25,10 +25,13 @@ cp deploy/launchd/ai.opengrokbot.gateway.plist ~/Library/LaunchAgents/
2525
launchctl load ~/Library/LaunchAgents/ai.opengrokbot.gateway.plist
2626
```
2727

28-
Docker Desktop has to come up with you: *Settings → General → Start Docker Desktop when you sign in*.
28+
If the teammates use Docker computers, Docker Desktop has to come up with you: *Settings → General → Start Docker
29+
Desktop when you sign in*. Local computers need no service — but a sign-in window can only appear in a desktop
30+
session, so keep the gateway a LaunchAgent of the user you sign in as, not a LaunchDaemon.
2931

3032
**Linux.** Use [`deploy/systemd/opengrokbot.service`](../deploy/systemd/opengrokbot.service): run it as a user
31-
in the `docker` group and keep the key in `/etc/opengrokbot.env` (mode `600`).
33+
in the `docker` group (for Docker computers; for local computers that user needs `bubblewrap` installed if commands
34+
are to be allowed) and keep the key in `/etc/opengrokbot.env` (mode `600`).
3235

3336
```bash
3437
sudo cp deploy/systemd/opengrokbot.service /etc/systemd/system/

‎docs/comparison.md‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ ships almost daily, so this table ages fast. Corrections welcome via PR — it o
99

1010
| Capability | Grok Bot | This stack | Notes |
1111
|---|---|---|---|
12-
| Always-on teammates | ✅ on xAI's cloud | ✅ one Docker container each | Yours runs where you say: Mac mini, NAS, $5 VPS |
12+
| Always-on teammates | ✅ on xAI's cloud | ✅ a container, or a local sandbox, each | Yours runs where you say: Mac mini, NAS, $5 VPS |
1313
| Whose computer | A cloud computer per member; xAI's wording says a member's bots share it | A separate container per teammate | Separate desks mean separate blast radii: one teammate's browser, files and logins are out of another's reach |
1414
| Watch its screen / take over | ✅ status, side preview, full-screen takeover | ✅ noVNC panel from the thread | |
1515
| Signing in | Secure Form fills logins from chat; 1Password on Mac; takeover as fallback | Takeover only: you sign in on its screen | Theirs is smoother; ours never lets a password pass through the gateway |
16-
| Work on your own machine | ✅ "Your computer" in the desktop app; web traffic can leave through your desktop | ❌ | A Docker-free local mode is planned ([local-computers.md](local-computers.md)) |
16+
| Work on your own machine | ✅ "Your computer" in the desktop app; web traffic can leave through your desktop | ✅ local computers (v0.4.0): a browser profile and a folder of its own on your machine, commands off until you allow them and sandboxed then | macOS and Linux; Windows still needs Docker ([local-computers.md](local-computers.md)) |
1717
| Named bots, persistent memory | ✅ | ✅ | Rules live in `MEMORY.md` outside the bot's computer; every change is a diff chip |
1818
| Forget a rule | ✅ | ✅ `forget_memory`, or remove it in the panel | |
1919
| Approval gate on outward actions | ✅ draft cards, Auto-review by a separate model | ✅ Approve / Discard, or a bare 👍 | Ours is held by instruction, not a sandbox — see [security.md](security.md) |
@@ -38,7 +38,7 @@ ships almost daily, so this table ages fast. Corrections welcome via PR — it o
3838
| Voice | ✅ voice chat and calls | ❌ | |
3939
| Apps | macOS, Windows and Linux desktop; iOS | A web client in your browser, reachable from other machines through a tunnel | Not tuned for phones yet |
4040
| Model choice | Grok only | Any OpenAI-compatible: Grok, Kimi, DeepSeek, local | `stub` runs with no key |
41-
| Setup | Zero (their infra) | `pnpm install` + one `docker build` | This is the price of custody |
41+
| Setup | Zero (their infra) | `pnpm install`; Docker only if you want sealed containers | This is the price of custody |
4242
| Your credentials live | xAI's cloud | Your disk | The actual point |
4343

4444
## The other two: Meta Muse and OpenAI dots
@@ -73,7 +73,7 @@ today they cannot act, but they can still load any page.
7373
| Item | Grok Bot | OpenGrokBot |
7474
|---|---|---|
7575
| Subscription | Comes with SuperGrok and Cursor plans from Pro up, with its own usage meter; past the included usage you upgrade or set an on-demand limit | $0 |
76-
| Compute | included | hardware you own, or a ~$5/mo VPS (2GB RAM min for Docker builds) |
76+
| Compute | included | hardware you own, or a ~$5/mo VPS (2GB RAM min if the teammates use Docker) |
7777
| Model usage | included up to the plan's allowance | your API bill; moderate single-bot usage on grok-4.5 ≈ single-digit $/mo; local model = $0 |
7878

7979
## What Grok Bot genuinely does better

‎docs/faq.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ Read [comparison.md](comparison.md) — including the "what Grok Bot genuinely d
2222
No. v0.2 runs its own gateway and its own containers, and never reads or writes an OpenClaw config. If you want the old v0.1 distribution path instead, it is in [openclaw-recipe/](openclaw-recipe/README.md) — and its `setup.sh` still refuses to overwrite an existing config, writing a merge file instead.
2323

2424
**Windows?**
25-
WSL2, with Docker Desktop's WSL2 backend for the bot computers.
25+
WSL2, with Docker Desktop's WSL2 backend for the bot computers. Local computers (no Docker) are macOS and Linux only for now.
2626

2727
**How much RAM does a VPS need?**
28-
2GB minimum. Each bot's container runs a real Chromium, so budget roughly 300–500MB per teammate that is actually awake. Computers start on demand and stop after an hour without use (`OPENGROKBOT_IDLE_STOP_MINUTES`), so idle teammates cost disk, not memory. Their logins survive the stop.
28+
2GB minimum. Each awake teammate runs a real Chromium — in its container, or headless on your machine — so budget roughly 300–500MB per teammate that is actually awake. Computers start on demand and stop after an hour without use (`OPENGROKBOT_IDLE_STOP_MINUTES`), so idle teammates cost disk, not memory. Their logins survive the stop.
2929

3030
**Why does it ask me to sign in?**
3131
The gateway can drive browsers that hold your sessions, so nothing talks to it without its token — not other websites you visit, not other devices on your network, not the bots themselves. Open the sign-in link it prints at startup once per browser; the token is in `gateway/data/auth-token`. Details in [security.md](security.md).

‎docs/local-computers.md‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Plan: teammates' computers without Docker
1+
# Teammates' computers without Docker
22

33
> **Status: the local computer has shipped for macOS and Linux** (step 1 below). The desktop app, the first-run
44
> wizard and the Apple container backend are still plans. The two questions this page once left open were settled
@@ -27,16 +27,17 @@ The gateway chooses at startup — Docker when the daemon answers, local otherwi
2727

2828
- **Out of your way.** Teammates work in a headless browser in the background — no windows popping up.
2929
- **Signing in gets simpler.** At a login wall, the teammate's browser reopens as a normal window on your desktop,
30-
on the page it was stuck on; you sign in there, click *I'm done signing in* in the panel (or just send it the next
31-
message), and it goes back to the background with the session in its own profile. No VNC in between.
30+
on the page it was stuck on; you sign in there, click *I'm done signing in* in the panel (your next message to it does the same;
31+
a routine firing meanwhile leaves the window alone), and it goes back to the background with the session in its own profile. No VNC in between.
3232
- **Watching still works.** The computer panel shows the browser's screen as a live stream (CDP screencast), view
3333
only.
3434
- **The browser keeps its own sandbox.** On the host, Chromium runs with its sandbox on (inside containers it
3535
cannot).
3636
- **Commands are off by default.** A local teammate gets a browser and its own folder; most of the work people
3737
hand off needs nothing more. You can turn commands on per teammate in its computer panel, and then they run in
3838
an OS sandbox that confines them to that teammate's folder: Seatbelt on macOS, bubblewrap on Linux — the same
39-
primitives developer agents use today. The switch refuses to turn on until the sandbox passes a self-check (a
39+
primitives developer agents use today. Your home directory is hidden from them, except the runtime managers
40+
(`~/.nvm`, `~/.volta`, `~/.pyenv`, `~/.cargo/bin`, …) they need to find `node` or `python`. The switch refuses to turn on until the sandbox passes a self-check (a
4041
write outside the folder and a read of the gateway token must both fail). What the sandbox does and does not
4142
promise is spelled out in [security.md](security.md#local-computers).
4243
- **No Linux userland.** A local teammate cannot `apt install` tools. Teammates that need that get a sealed

‎docs/security.md‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ injection — that follows an agent wherever it runs. This page is precise about
2020
| Bots cannot reach each other | All bot computers share one Docker network with container-to-container traffic switched off. And because on Docker Desktop a container can still reach ports published on the host, everything a computer publishes wants that computer's own secret: its shell/file shim and its browser control port (CDP) a per-container token, its screen a per-container VNC password. |
2121
| Each Docker computer is a cage | Its own container with memory, CPU and process limits, `no-new-privileges`, and only its own workspace mounted. Every port is published to `127.0.0.1` only. |
2222
| A local computer's files stay in its folder | `read_file` and `write_file` resolve inside that teammate's folder — `/workspace` maps to it — and a path that leaves it by name or through a symlink is refused. Its browser profile lives outside that folder, so the teammate cannot read its own cookie store through the file tools. |
23-
| A local computer's commands are off, then caged | Commands are off until you turn them on for that teammate in its panel. On, they run under Seatbelt (macOS) or bubblewrap (Linux): they can write only the teammate's folder and a private tmp; the data dir (gateway token, other teammates' folders and profiles) and your key folders (`~/.ssh`, `~/.aws`, `~/.gnupg`, the GitHub CLI, your own Chrome profile) are unreadable; `HOME` points at the folder and the environment is a short whitelist. The switch refuses to turn on until a self-check shows the sandbox blocks a write outside the folder and a read of the gateway token. A command that outlives its timeout, or that you stop, is killed with its whole process group. |
23+
| A local computer's commands are off, then caged | Commands are off until you turn them on for that teammate in its panel. On, they run under Seatbelt (macOS) or bubblewrap (Linux): they can write only the teammate's folder and a private tmp; your whole home directory — keys, documents, other projects, your own browser profile, the gateway's data dir — is unreadable, except the runtime managers (`~/.nvm`, `~/.volta`, `~/.pyenv`, `~/.cargo/bin`, …) that are put back read-only; a data dir outside your home is hidden too; `HOME` points at the folder and the environment is a short whitelist. The switch refuses to turn on until a self-check shows the sandbox blocks a write outside the folder, a read of the gateway token and a listing of your home directory. A command that outlives its timeout, or that you stop, is killed with its whole process group. |
2424
| A bot cannot put code in front of you | The screen page and its noVNC code are served by the gateway from its own copy; only the raw VNC stream comes from the bot's computer. Nothing a bot changes inside its container reaches your browser as a page. |
2525
| Standing rules only change through the chip | `MEMORY.md` lives outside the bot's workspace. The only ways to change it are `save_memory`, `forget_memory` and the remove button in the computer panel, and each of them posts a diff chip; a `MEMORY.md` a bot writes into its own workspace is ignored. Screenshots — the evidence — are stored outside it too. |
2626
| Handoffs are allowlisted | By default only the chief of staff can reach everyone. Peer directions need `OPENGROKBOT_A2A_ALLOW`, and relays stop after two hops. |
@@ -86,6 +86,9 @@ A local computer is weaker than a container in ways you should know before you g
8686
system, not the network: a command can reach anything your machine can, including services on `localhost`. It
8787
cannot read the gateway token, so it cannot drive the gateway — but a service of yours that trusts localhost
8888
without a password is reachable.
89+
- **System services stay reachable.** The sandbox confines files, not the operating system: a command can read
90+
anything outside your home that your user can (system libraries, `/opt`, `/etc`), and on macOS it can talk to any
91+
Mach service (the pasteboard among them).
8992
- **No resource limits.** Nothing caps a local teammate's memory or CPU; a runaway command is killed only by its
9093
timeout (ten minutes at most) or the stop button.
9194
- **The profile is a file.** The teammate's cookies live under `<data>/bots/<id>/browser`, readable by any program

0 commit comments

Comments
 (0)